├── .gitignore ├── AUTHORS ├── COPYING ├── HACKING ├── INSTALL ├── Makefile.am ├── NEWS ├── README ├── THANKS ├── TODO ├── autogen.sh ├── configure.ac ├── doc ├── Makefile.am └── doxygen.cfg ├── examples ├── Makefile.am ├── enroll.c ├── img_capture.c ├── img_capture_continuous.c ├── verify.c └── verify_live.c ├── libfprint.pc.in └── libfprint ├── Makefile.am ├── aeslib.c ├── aeslib.h ├── async.c ├── core.c ├── data.c ├── drivers ├── aes1610.c ├── aes2501.c ├── aes2501.h ├── aes4000.c ├── fdu2000.c ├── upeksonly.c ├── upektc.c ├── upekts.c ├── uru4000.c └── vcom5s.c ├── drv.c ├── fp_internal.h ├── fprint-list-hal-info.c ├── fprint.h ├── imagemagick.c ├── img.c ├── imgdev.c ├── nbis ├── bozorth3 │ ├── bozorth3.c │ ├── bz_alloc.c │ ├── bz_drvrs.c │ ├── bz_gbls.c │ ├── bz_io.c │ └── bz_sort.c ├── include │ ├── bozorth.h │ ├── bz_array.h │ ├── defs.h │ ├── lfs.h │ ├── log.h │ ├── morph.h │ └── sunrast.h └── mindtct │ ├── binar.c │ ├── block.c │ ├── contour.c │ ├── detect.c │ ├── dft.c │ ├── free.c │ ├── globals.c │ ├── imgutil.c │ ├── init.c │ ├── line.c │ ├── log.c │ ├── loop.c │ ├── maps.c │ ├── matchpat.c │ ├── minutia.c │ ├── morph.c │ ├── quality.c │ ├── remove.c │ ├── ridges.c │ ├── shape.c │ ├── sort.c │ └── util.c ├── poll.c └── sync.c /.gitignore: -------------------------------------------------------------------------------- 1 | ltmain.sh 2 | missing 3 | stamp-h1 4 | libtool 5 | *.la 6 | *.lo 7 | *.o 8 | *.swp 9 | Makefile 10 | Makefile.in 11 | config.h* 12 | aclocal.m4 13 | autom4te.cache 14 | config.guess 15 | config.log 16 | config.status 17 | config.sub 18 | configure 19 | depcomp 20 | install-sh 21 | .deps 22 | .libs 23 | compile 24 | ChangeLog 25 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Copyright (C) 2007 Daniel Drake 2 | Copyright (C) 2006-2007 Timo Hoenig 3 | Copyright (C) 2006 Pavel Machek 4 | Copyright (C) 1999 Erik Walthinsen 5 | Copyright (C) 2004,2006 Thomas Vander Stichele 6 | Copyright (C) 2007 Cyrille Bagard 7 | Copyright (C) 2007 Vasily Khoruzhick 8 | Copyright (C) 2007 Jan-Michael Brummer 9 | Copyright (C) 2007 Anthony Bretaudeau 10 | -------------------------------------------------------------------------------- /HACKING: -------------------------------------------------------------------------------- 1 | Copyright notices 2 | ================= 3 | 4 | If you make a contribution substantial enough to add or update a copyright 5 | notice on a file, such notice must be mirrored in the AUTHORS file. This is 6 | to make it easy for people to comply to section 6 of the LGPL, which states 7 | that a "work that uses the Library" must include copyright notices from 8 | this library. By providing them all in one place, hopefully we save such 9 | users some time. 10 | 11 | 12 | USB 13 | === 14 | 15 | At the time of development, there are no known consumer fingerprint readers 16 | which do not operate over the USB bus. Therefore the library is designed around 17 | the fact that each driver drivers USB devices, and each device is a USB device. 18 | If we were to ever support a non-USB device, some rearchitecting would be 19 | needed, but this would not be a substantial task. 20 | 21 | 22 | GLib 23 | ==== 24 | 25 | Although the library uses GLib internally, libfprint is designed to provide 26 | a completely neutral interface to it's application users. So, the public 27 | APIs should never return GLib data types or anything like that. 28 | 29 | 30 | Two-faced-ness 31 | ============== 32 | 33 | Like any decent library, this one is designed to provide a stable and 34 | documented API to it's users: applications. Clear distinction is made between 35 | data available internally in the library, and data/functions available to 36 | the applications. 37 | 38 | This library is confused a little by the fact that there is another 'interface' 39 | at hand: the internal interface provided to drivers. So, we effectively end 40 | up with 2 APIs: 41 | 42 | 1. The external-facing API for applications 43 | 2. The internal API for fingerprint drivers 44 | 45 | Non-static functions which are intended for internal use only are prepended 46 | with the "fpi_" prefix. 47 | 48 | 49 | API stability 50 | ============= 51 | 52 | No API stability has been promised to anyone: go wild, there's no issue with 53 | breaking APIs at this point in time. 54 | 55 | 56 | Portability 57 | =========== 58 | 59 | libfprint is primarily written for Linux. However, I'm interested in 60 | supporting efforts to port this to other operating systems too. 61 | 62 | You should ensure code is portable wherever possible. Try and use GLib rather 63 | than OS-specific features. 64 | 65 | Endianness must be considered in all code. libfprint must support both big- 66 | and little-endian systems. 67 | 68 | 69 | Coding Style 70 | ============ 71 | 72 | This project follows Linux kernel coding style but with a tab width of 4. 73 | 74 | 75 | Documentation 76 | ============= 77 | 78 | All additions of public API functions must be accompanied with doxygen 79 | comments. 80 | 81 | All changes which potentially change the behaviour of the public API must 82 | be reflected by updating the appropriate doxygen comments. 83 | 84 | 85 | Contributing 86 | ============ 87 | 88 | Patches should be sent to the fprint mailing list detailed on the website. 89 | A subscription is required. 90 | 91 | Information about libfprint development repositories can be found here: 92 | http://www.reactivated.net/fprint/Libfprint_development 93 | 94 | If you're looking for ideas for things to work on, look at the TODO file or 95 | grep the source code for FIXMEs. 96 | 97 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ************************* 3 | 4 | Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 5 | 2006 Free Software Foundation, Inc. 6 | 7 | This file is free documentation; the Free Software Foundation gives 8 | unlimited permission to copy, distribute and modify it. 9 | 10 | Basic Installation 11 | ================== 12 | 13 | Briefly, the shell commands `./configure; make; make install' should 14 | configure, build, and install this package. The following 15 | more-detailed instructions are generic; see the `README' file for 16 | instructions specific to this package. 17 | 18 | The `configure' shell script attempts to guess correct values for 19 | various system-dependent variables used during compilation. It uses 20 | those values to create a `Makefile' in each directory of the package. 21 | It may also create one or more `.h' files containing system-dependent 22 | definitions. Finally, it creates a shell script `config.status' that 23 | you can run in the future to recreate the current configuration, and a 24 | file `config.log' containing compiler output (useful mainly for 25 | debugging `configure'). 26 | 27 | It can also use an optional file (typically called `config.cache' 28 | and enabled with `--cache-file=config.cache' or simply `-C') that saves 29 | the results of its tests to speed up reconfiguring. Caching is 30 | disabled by default to prevent problems with accidental use of stale 31 | cache files. 32 | 33 | If you need to do unusual things to compile the package, please try 34 | to figure out how `configure' could check whether to do them, and mail 35 | diffs or instructions to the address given in the `README' so they can 36 | be considered for the next release. If you are using the cache, and at 37 | some point `config.cache' contains results you don't want to keep, you 38 | may remove or edit it. 39 | 40 | The file `configure.ac' (or `configure.in') is used to create 41 | `configure' by a program called `autoconf'. You need `configure.ac' if 42 | you want to change it or regenerate `configure' using a newer version 43 | of `autoconf'. 44 | 45 | The simplest way to compile this package is: 46 | 47 | 1. `cd' to the directory containing the package's source code and type 48 | `./configure' to configure the package for your system. 49 | 50 | Running `configure' might take a while. While running, it prints 51 | some messages telling which features it is checking for. 52 | 53 | 2. Type `make' to compile the package. 54 | 55 | 3. Optionally, type `make check' to run any self-tests that come with 56 | the package. 57 | 58 | 4. Type `make install' to install the programs and any data files and 59 | documentation. 60 | 61 | 5. You can remove the program binaries and object files from the 62 | source code directory by typing `make clean'. To also remove the 63 | files that `configure' created (so you can compile the package for 64 | a different kind of computer), type `make distclean'. There is 65 | also a `make maintainer-clean' target, but that is intended mainly 66 | for the package's developers. If you use it, you may have to get 67 | all sorts of other programs in order to regenerate files that came 68 | with the distribution. 69 | 70 | Compilers and Options 71 | ===================== 72 | 73 | Some systems require unusual options for compilation or linking that the 74 | `configure' script does not know about. Run `./configure --help' for 75 | details on some of the pertinent environment variables. 76 | 77 | You can give `configure' initial values for configuration parameters 78 | by setting variables in the command line or in the environment. Here 79 | is an example: 80 | 81 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix 82 | 83 | *Note Defining Variables::, for more details. 84 | 85 | Compiling For Multiple Architectures 86 | ==================================== 87 | 88 | You can compile the package for more than one kind of computer at the 89 | same time, by placing the object files for each architecture in their 90 | own directory. To do this, you can use GNU `make'. `cd' to the 91 | directory where you want the object files and executables to go and run 92 | the `configure' script. `configure' automatically checks for the 93 | source code in the directory that `configure' is in and in `..'. 94 | 95 | With a non-GNU `make', it is safer to compile the package for one 96 | architecture at a time in the source code directory. After you have 97 | installed the package for one architecture, use `make distclean' before 98 | reconfiguring for another architecture. 99 | 100 | Installation Names 101 | ================== 102 | 103 | By default, `make install' installs the package's commands under 104 | `/usr/local/bin', include files under `/usr/local/include', etc. You 105 | can specify an installation prefix other than `/usr/local' by giving 106 | `configure' the option `--prefix=PREFIX'. 107 | 108 | You can specify separate installation prefixes for 109 | architecture-specific files and architecture-independent files. If you 110 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses 111 | PREFIX as the prefix for installing programs and libraries. 112 | Documentation and other data files still use the regular prefix. 113 | 114 | In addition, if you use an unusual directory layout you can give 115 | options like `--bindir=DIR' to specify different values for particular 116 | kinds of files. Run `configure --help' for a list of the directories 117 | you can set and what kinds of files go in them. 118 | 119 | If the package supports it, you can cause programs to be installed 120 | with an extra prefix or suffix on their names by giving `configure' the 121 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. 122 | 123 | Optional Features 124 | ================= 125 | 126 | Some packages pay attention to `--enable-FEATURE' options to 127 | `configure', where FEATURE indicates an optional part of the package. 128 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE 129 | is something like `gnu-as' or `x' (for the X Window System). The 130 | `README' should mention any `--enable-' and `--with-' options that the 131 | package recognizes. 132 | 133 | For packages that use the X Window System, `configure' can usually 134 | find the X include and library files automatically, but if it doesn't, 135 | you can use the `configure' options `--x-includes=DIR' and 136 | `--x-libraries=DIR' to specify their locations. 137 | 138 | Specifying the System Type 139 | ========================== 140 | 141 | There may be some features `configure' cannot figure out automatically, 142 | but needs to determine by the type of machine the package will run on. 143 | Usually, assuming the package is built to be run on the _same_ 144 | architectures, `configure' can figure that out, but if it prints a 145 | message saying it cannot guess the machine type, give it the 146 | `--build=TYPE' option. TYPE can either be a short name for the system 147 | type, such as `sun4', or a canonical name which has the form: 148 | 149 | CPU-COMPANY-SYSTEM 150 | 151 | where SYSTEM can have one of these forms: 152 | 153 | OS KERNEL-OS 154 | 155 | See the file `config.sub' for the possible values of each field. If 156 | `config.sub' isn't included in this package, then this package doesn't 157 | need to know the machine type. 158 | 159 | If you are _building_ compiler tools for cross-compiling, you should 160 | use the option `--target=TYPE' to select the type of system they will 161 | produce code for. 162 | 163 | If you want to _use_ a cross compiler, that generates code for a 164 | platform different from the build platform, you should specify the 165 | "host" platform (i.e., that on which the generated programs will 166 | eventually be run) with `--host=TYPE'. 167 | 168 | Sharing Defaults 169 | ================ 170 | 171 | If you want to set default values for `configure' scripts to share, you 172 | can create a site shell script called `config.site' that gives default 173 | values for variables like `CC', `cache_file', and `prefix'. 174 | `configure' looks for `PREFIX/share/config.site' if it exists, then 175 | `PREFIX/etc/config.site' if it exists. Or, you can set the 176 | `CONFIG_SITE' environment variable to the location of the site script. 177 | A warning: not all `configure' scripts look for a site script. 178 | 179 | Defining Variables 180 | ================== 181 | 182 | Variables not defined in a site shell script can be set in the 183 | environment passed to `configure'. However, some packages may run 184 | configure again during the build, and the customized values of these 185 | variables may be lost. In order to avoid this problem, you should set 186 | them in the `configure' command line, using `VAR=value'. For example: 187 | 188 | ./configure CC=/usr/local2/bin/gcc 189 | 190 | causes the specified `gcc' to be used as the C compiler (unless it is 191 | overridden in the site shell script). 192 | 193 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to 194 | an Autoconf bug. Until the bug is fixed you can use this workaround: 195 | 196 | CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash 197 | 198 | `configure' Invocation 199 | ====================== 200 | 201 | `configure' recognizes the following options to control how it operates. 202 | 203 | `--help' 204 | `-h' 205 | Print a summary of the options to `configure', and exit. 206 | 207 | `--version' 208 | `-V' 209 | Print the version of Autoconf used to generate the `configure' 210 | script, and exit. 211 | 212 | `--cache-file=FILE' 213 | Enable the cache: use and save the results of the tests in FILE, 214 | traditionally `config.cache'. FILE defaults to `/dev/null' to 215 | disable caching. 216 | 217 | `--config-cache' 218 | `-C' 219 | Alias for `--cache-file=config.cache'. 220 | 221 | `--quiet' 222 | `--silent' 223 | `-q' 224 | Do not print messages saying which checks are being made. To 225 | suppress all normal output, redirect it to `/dev/null' (any error 226 | messages will still be shown). 227 | 228 | `--srcdir=DIR' 229 | Look for the package's source code in directory DIR. Usually 230 | `configure' can determine that directory automatically. 231 | 232 | `configure' also accepts some other, not widely useful, options. Run 233 | `configure --help' for more details. 234 | 235 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | AUTOMAKE_OPTIONS = dist-bzip2 2 | ACLOCAL_AMFLAGS = -I m4 3 | EXTRA_DIST = THANKS TODO HACKING libfprint.pc.in 4 | DISTCLEANFILES = ChangeLog libfprint.pc 5 | 6 | SUBDIRS = libfprint doc 7 | 8 | if BUILD_EXAMPLES 9 | SUBDIRS += examples 10 | endif 11 | 12 | pkgconfigdir=$(libdir)/pkgconfig 13 | pkgconfig_DATA=libfprint.pc 14 | 15 | .PHONY: ChangeLog dist-up 16 | ChangeLog: 17 | git --git-dir $(top_srcdir)/.git log > ChangeLog || touch ChangeLog 18 | 19 | dist-hook: ChangeLog 20 | 21 | dist-up: dist 22 | rsync $(distdir).tar.bz2 frs.sourceforge.net:uploads/ 23 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | This file lists notable changes in each release. For the full history of all 2 | changes, see ChangeLog. 3 | 4 | 2007-12-07: v0.0.5 release 5 | * AES1610 imaging improvements 6 | * Internal cleanups for Authentec drivers 7 | * Add support for latest Microsoft Fingerprint Scanner hardware revision 8 | 9 | 2007-11-22: v0.0.4 release 10 | * Enable AES1610 driver thanks to Michele B 11 | * Implement identification: one-to-many fingerprint matching (Daniel Drake) 12 | 13 | 2007-11-19: v0.0.3 release 14 | * Add API to access minutiae (Daniel Drake) 15 | * Add API to delete enroll data (Daniel Drake) 16 | * Add Authentec AES1610 driver (Anthony Bretaudeau) 17 | 18 | 2007-11-17: v0.0.2 release 19 | * Detect reversed scans on AES2501 (Vasily Khoruzhick) 20 | * Improved AES2501 scanning 21 | * Compatibility with older ImageMagick versions 22 | * Add UPEK TouchChip driver (Jan-Michael Brummer) 23 | * Add binarization API 24 | 25 | 2007-11-15: v0.0.1 release 26 | * Initial release 27 | 28 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | libfprint 2 | ========= 3 | 4 | libfprint is part of the fprint project: 5 | http://www.reactivated.net/fprint 6 | 7 | libfprint was originally developed as part of an academic project at the 8 | University of Manchester with the aim of hiding differences between different 9 | consumer fingerprint scanners and providing a single uniform API to application 10 | developers. The ultimate goal of the fprint project is to make fingerprint 11 | scanners widely and easily usable under common Linux environments. 12 | 13 | The academic university project runs off a codebase maintained separately 14 | from this one, although I try to keep them as similar as possible (I'm not 15 | hiding anything in the academic branch, it's just the open source release 16 | contains some commits excluded from the academic project). 17 | 18 | THE UNIVERSITY OF MANCHESTER DOES NOT ENDORSE THIS THIS SOFTWARE RELEASE AND 19 | IS IN NO WAY RESPONSIBLE FOR THE CODE CONTAINED WITHIN, OR ANY DAMAGES CAUSED 20 | BY USING OR DISTRIBUTING THE SOFTWARE. Development does not happen on 21 | university computers and the project is not hosted at the university either. 22 | 23 | For more information on libfprint, supported devices, API documentation, etc., 24 | see the homepage: 25 | http://www.reactivated.net/fprint/Libfprint 26 | 27 | libfprint is licensed under the GNU LGPL version 2.1. See the COPYING file 28 | for the license text. 29 | 30 | Section 6 of the license states that for compiled works that use this 31 | library, such works must include libfprint copyright notices alongside the 32 | copyright notices for the other parts of the work. We have attempted to 33 | make this process slightly easier for you by grouping these all in one place: 34 | the AUTHORS file. 35 | 36 | libfprint includes code from NIST's NBIS software distribution: 37 | http://fingerprint.nist.gov/NBIS/index.html 38 | We include bozorth3 from the US export controlled distribution. We have 39 | determined that it is fine to ship bozorth3 in an open source project, 40 | see http://reactivated.net/fprint/wiki/US_export_control 41 | 42 | -------------------------------------------------------------------------------- /THANKS: -------------------------------------------------------------------------------- 1 | Tony Vroon - hardware donations 2 | Gerrie Mansur from Security Database BV (http://www.securitydatabase.net/) - hardware donations 3 | Joaquin Custodio - hardware donations 4 | TimeTrex (http://www.timetrex.com/) - hardware donations 5 | Craig Watson (NIST) 6 | James Vasile (SFLC) 7 | Toby Howard (University of Manchester) 8 | Seemant Kulleen 9 | Pavel Herrman 10 | Bastien Nocera 11 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | LIBRARY 2 | ======= 3 | test suite against NFIQ compliance set 4 | make library optionally asynchronous and maybe thread-safe 5 | nbis cleanups 6 | API function to determine if img device supports uncond. capture 7 | race-free way of saying "save this print but don't overwrite" 8 | 9 | NEW DRIVERS 10 | =========== 11 | Sunplus 895 driver 12 | AES3400/3500 driver 13 | ID Mouse driver 14 | Support for 2nd generation MS devices 15 | Support for 2nd generation UPEK devices 16 | 17 | IMAGING 18 | ======= 19 | ignore first frame or two with aes2501 20 | aes2501: increase threshold "sum" for end-of-image detection 21 | aes2501 gain calibration 22 | aes4000 gain calibration 23 | aes4000 resampling 24 | PPMM parameter to get_minutiae seems to have no effect 25 | nbis minutiae should be stored in endian-independent format 26 | 27 | PORTABILITY 28 | =========== 29 | OpenBSD can't do -Wshadow or visibility 30 | OpenBSD: add compat codes for ENOTSUP ENODATA and EPROTO 31 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | libtoolize --copy --force || exit 1 3 | aclocal || exit 1 4 | autoheader || exit 1 5 | autoconf || exit 1 6 | automake -a -c || exit 1 7 | ./configure --enable-maintainer-mode --enable-examples-build \ 8 | --enable-x11-examples-build --enable-debug-log $* 9 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_INIT([libfprint], [0.1.0-pre2]) 2 | AM_INIT_AUTOMAKE 3 | AC_CONFIG_MACRO_DIR([m4]) 4 | AC_CONFIG_SRCDIR([libfprint/core.c]) 5 | AM_CONFIG_HEADER([config.h]) 6 | 7 | AC_PREREQ([2.50]) 8 | AC_PROG_CC 9 | AC_PROG_LIBTOOL 10 | AC_C_INLINE 11 | AM_PROG_CC_C_O 12 | AC_DEFINE([_GNU_SOURCE], [], [Use GNU extensions]) 13 | 14 | # Library versioning 15 | lt_major="0" 16 | lt_revision="0" 17 | lt_age="0" 18 | AC_SUBST(lt_major) 19 | AC_SUBST(lt_revision) 20 | AC_SUBST(lt_age) 21 | 22 | all_drivers="upekts upektc upeksonly vcom5s uru4000 fdu2000 aes1610 aes2501 aes4000" 23 | 24 | require_imagemagick='no' 25 | require_aeslib='no' 26 | enable_upekts='no' 27 | enable_upektc='no' 28 | enable_upeksonly='no' 29 | enable_vcom5s='no' 30 | enable_uru4000='no' 31 | enable_fdu2000='no' 32 | enable_aes1610='no' 33 | enable_aes2501='no' 34 | enable_aes4000='no' 35 | 36 | AC_ARG_WITH([drivers],[AS_HELP_STRING([--with-drivers], 37 | [List of drivers to enable])], 38 | [drivers="$withval"], 39 | [drivers="$all_drivers"]) 40 | 41 | for driver in `echo ${drivers} | sed -e 's/,/ /g' -e 's/,$//g'`; do 42 | case ${driver} in 43 | upekts) 44 | AC_DEFINE([ENABLE_UPEKTS], [], [Build UPEK TouchStrip driver]) 45 | enable_upekts="yes" 46 | ;; 47 | upektc) 48 | AC_DEFINE([ENABLE_UPEKTC], [], [Build UPEK TouchChip driver]) 49 | enable_upektc="yes" 50 | ;; 51 | upeksonly) 52 | AC_DEFINE([ENABLE_UPEKSONLY], [], [Build UPEK TouchStrip sensor-only driver]) 53 | enable_upeksonly="yes" 54 | ;; 55 | uru4000) 56 | AC_DEFINE([ENABLE_URU4000], [], [Build Digital Persona U.are.U 4000 driver]) 57 | enable_uru4000="yes" 58 | ;; 59 | fdu2000) 60 | AC_DEFINE([ENABLE_FDU2000], [], [Build Secugen FDU 2000 driver]) 61 | enable_fdu2000="yes" 62 | ;; 63 | vcom5s) 64 | AC_DEFINE([ENABLE_VCOM5S], [], [Build Veridicom 5thSense driver]) 65 | enable_vcom5s="yes" 66 | ;; 67 | aes2501) 68 | AC_DEFINE([ENABLE_AES2501], [], [Build AuthenTec AES2501 driver]) 69 | require_aeslib="yes" 70 | enable_aes2501="yes" 71 | ;; 72 | aes1610) 73 | AC_DEFINE([ENABLE_AES1610], [], [Build AuthenTec AES1610 driver]) 74 | require_aeslib="yes" 75 | enable_aes1610="yes" 76 | ;; 77 | aes4000) 78 | AC_DEFINE([ENABLE_AES4000], [], [Build AuthenTec AES4000 driver]) 79 | require_aeslib="yes" 80 | require_imagemagick="yes" 81 | enable_aes4000="yes" 82 | ;; 83 | esac 84 | done 85 | 86 | AM_CONDITIONAL([ENABLE_UPEKTS], [test "$enable_upekts" != "no"]) 87 | #AM_CONDITIONAL([ENABLE_UPEKTC], [test "$enable_upektc" != "no"]) 88 | AM_CONDITIONAL([ENABLE_UPEKSONLY], [test "$enable_upeksonly" != "no"]) 89 | AM_CONDITIONAL([ENABLE_VCOM5S], [test "$enable_vcom5s" != "no"]) 90 | AM_CONDITIONAL([ENABLE_URU4000], [test "$enable_uru4000" != "no"]) 91 | #AM_CONDITIONAL([ENABLE_FDU2000], [test "$enable_fdu2000" != "no"]) 92 | #AM_CONDITIONAL([ENABLE_AES1610], [test "$enable_aes1610" != "no"]) 93 | AM_CONDITIONAL([ENABLE_AES2501], [test "$enable_aes2501" != "no"]) 94 | AM_CONDITIONAL([ENABLE_AES4000], [test "$enable_aes4000" != "no"]) 95 | AM_CONDITIONAL([REQUIRE_IMAGEMAGICK], [test "$require_imagemagick" != "no"]) 96 | AM_CONDITIONAL([REQUIRE_AESLIB], [test "$require_aeslib" != "no"]) 97 | 98 | 99 | PKG_CHECK_MODULES(LIBUSB, [libusb-1.0 >= 0.9.1]) 100 | AC_SUBST(LIBUSB_CFLAGS) 101 | AC_SUBST(LIBUSB_LIBS) 102 | 103 | # check for OpenSSL's libcrypto 104 | PKG_CHECK_MODULES(CRYPTO, "libcrypto") 105 | AC_SUBST(CRYPTO_CFLAGS) 106 | AC_SUBST(CRYPTO_LIBS) 107 | 108 | PKG_CHECK_MODULES(GLIB, "glib-2.0") 109 | AC_SUBST(GLIB_CFLAGS) 110 | AC_SUBST(GLIB_LIBS) 111 | 112 | if test "$require_imagemagick" != "no"; then 113 | PKG_CHECK_MODULES(IMAGEMAGICK, "ImageMagick") 114 | AC_SUBST(IMAGEMAGICK_CFLAGS) 115 | AC_SUBST(IMAGEMAGICK_LIBS) 116 | fi; 117 | 118 | # Examples build 119 | AC_ARG_ENABLE([examples-build], [AS_HELP_STRING([--enable-examples-build], 120 | [build example applications (default n)])], 121 | [build_examples=$enableval], 122 | [build_examples='no']) 123 | AM_CONDITIONAL([BUILD_EXAMPLES], [test "x$build_examples" != "xno"]) 124 | 125 | # Examples build 126 | AC_ARG_ENABLE([x11-examples-build], [AS_HELP_STRING([--enable-x11-examples-build], 127 | [build X11 example applications (default n)])], 128 | [build_x11_examples=$enableval], 129 | [build_x11_examples='no']) 130 | AM_CONDITIONAL([BUILD_X11_EXAMPLES], [test "x$build_x11_examples" != "xno"]) 131 | 132 | 133 | if test "x$build_x11_examples" != "xno"; then 134 | # check for Xv extensions 135 | # imported from Coriander 136 | AC_DEFUN([AC_CHECK_XV],[ 137 | AC_SUBST(XV_CFLAGS) 138 | AC_SUBST(XV_LIBS) 139 | AC_MSG_CHECKING(for Xv extensions) 140 | AC_TRY_COMPILE([ 141 | #include 142 | #include ],[ 143 | int main(void) { (void) XvGetPortAttribute(0, 0, 0, 0); return 0; } 144 | ],xv=yes,xv=no); 145 | AC_MSG_RESULT($xv) 146 | if test x$xv = xyes; then 147 | XV_LIBS="-lXv -lXext" 148 | XV_CFLAGS="" 149 | AC_DEFINE(HAVE_XV,1,[defined if XV video overlay is available]) 150 | else 151 | AC_MSG_ERROR([XV is required for X11 examples]) 152 | fi 153 | ]) 154 | AC_CHECK_XV 155 | fi 156 | 157 | # Message logging 158 | AC_ARG_ENABLE([log], [AS_HELP_STRING([--disable-log], [disable all logging])], 159 | [log_enabled=$enableval], 160 | [log_enabled='yes']) 161 | if test "x$log_enabled" != "xno"; then 162 | AC_DEFINE([ENABLE_LOGGING], 1, [Message logging]) 163 | fi 164 | 165 | AC_ARG_ENABLE([debug-log], [AS_HELP_STRING([--enable-debug-log], 166 | [enable debug logging (default n)])], 167 | [debug_log_enabled=$enableval], 168 | [debug_log_enabled='no']) 169 | if test "x$debug_log_enabled" != "xno"; then 170 | AC_DEFINE([ENABLE_DEBUG_LOGGING], 1, [Debug message logging]) 171 | fi 172 | 173 | # Restore gnu89 inline semantics on gcc 4.3 and newer 174 | saved_cflags="$CFLAGS" 175 | CFLAGS="$CFLAGS -fgnu89-inline" 176 | AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]), inline_cflags="-fgnu89-inline", inline_cflags="") 177 | CFLAGS="$saved_cflags" 178 | 179 | AC_DEFINE([API_EXPORTED], [__attribute__((visibility("default")))], [Default visibility]) 180 | AM_CFLAGS="-std=gnu99 $inline_cflags -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration -Wno-pointer-sign -Wshadow" 181 | AC_SUBST(AM_CFLAGS) 182 | 183 | AC_CONFIG_FILES([libfprint.pc] [Makefile] [libfprint/Makefile] [examples/Makefile] [doc/Makefile]) 184 | AC_OUTPUT 185 | 186 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | EXTRA_DIST = doxygen.cfg 2 | 3 | docs: doxygen.cfg 4 | doxygen $^ 5 | 6 | docs-upload: docs 7 | ln -s html api 8 | ncftpput -f ~/.ncftp/reactivated -m -R httpdocs/fprint api/ 9 | rm -f api 10 | 11 | -------------------------------------------------------------------------------- /examples/Makefile.am: -------------------------------------------------------------------------------- 1 | INCLUDES = -I$(top_srcdir) 2 | noinst_PROGRAMS = verify_live enroll verify img_capture 3 | 4 | verify_live_SOURCES = verify_live.c 5 | verify_live_LDADD = ../libfprint/libfprint.la -lfprint 6 | 7 | enroll_SOURCES = enroll.c 8 | enroll_LDADD = ../libfprint/libfprint.la -lfprint 9 | 10 | verify_SOURCES = verify.c 11 | verify_LDADD = ../libfprint/libfprint.la -lfprint 12 | 13 | img_capture_SOURCES = img_capture.c 14 | img_capture_LDADD = ../libfprint/libfprint.la -lfprint 15 | 16 | if BUILD_X11_EXAMPLES 17 | noinst_PROGRAMS += img_capture_continuous 18 | 19 | img_capture_continuous_CFLAGS = $(X_CFLAGS) $(XV_CFLAGS) 20 | img_capture_continuous_SOURCES = img_capture_continuous.c 21 | img_capture_continuous_LDADD = ../libfprint/libfprint.la -lfprint $(X_LIBS) $(X_PRE_LIBS) $(XV_LIBS) -lX11 $(X_EXTRA_LIBS); 22 | endif 23 | 24 | -------------------------------------------------------------------------------- /examples/enroll.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Example fingerprint enrollment program 3 | * Enrolls your right index finger and saves the print to disk 4 | * Copyright (C) 2007 Daniel Drake 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs) 28 | { 29 | struct fp_dscv_dev *ddev = discovered_devs[0]; 30 | struct fp_driver *drv; 31 | if (!ddev) 32 | return NULL; 33 | 34 | drv = fp_dscv_dev_get_driver(ddev); 35 | printf("Found device claimed by %s driver\n", fp_driver_get_full_name(drv)); 36 | return ddev; 37 | } 38 | 39 | struct fp_print_data *enroll(struct fp_dev *dev) { 40 | struct fp_print_data *enrolled_print = NULL; 41 | int r; 42 | 43 | printf("You will need to successfully scan your finger %d times to " 44 | "complete the process.\n", fp_dev_get_nr_enroll_stages(dev)); 45 | 46 | do { 47 | struct fp_img *img = NULL; 48 | 49 | sleep(1); 50 | printf("\nScan your finger now.\n"); 51 | 52 | r = fp_enroll_finger_img(dev, &enrolled_print, &img); 53 | if (img) { 54 | fp_img_save_to_file(img, "enrolled.pgm"); 55 | printf("Wrote scanned image to enrolled.pgm\n"); 56 | fp_img_free(img); 57 | } 58 | if (r < 0) { 59 | printf("Enroll failed with error %d\n", r); 60 | return NULL; 61 | } 62 | 63 | switch (r) { 64 | case FP_ENROLL_COMPLETE: 65 | printf("Enroll complete!\n"); 66 | break; 67 | case FP_ENROLL_FAIL: 68 | printf("Enroll failed, something wen't wrong :(\n"); 69 | return NULL; 70 | case FP_ENROLL_PASS: 71 | printf("Enroll stage passed. Yay!\n"); 72 | break; 73 | case FP_ENROLL_RETRY: 74 | printf("Didn't quite catch that. Please try again.\n"); 75 | break; 76 | case FP_ENROLL_RETRY_TOO_SHORT: 77 | printf("Your swipe was too short, please try again.\n"); 78 | break; 79 | case FP_ENROLL_RETRY_CENTER_FINGER: 80 | printf("Didn't catch that, please center your finger on the " 81 | "sensor and try again.\n"); 82 | break; 83 | case FP_ENROLL_RETRY_REMOVE_FINGER: 84 | printf("Scan failed, please remove your finger and then try " 85 | "again.\n"); 86 | break; 87 | } 88 | } while (r != FP_ENROLL_COMPLETE); 89 | 90 | if (!enrolled_print) { 91 | fprintf(stderr, "Enroll complete but no print?\n"); 92 | return NULL; 93 | } 94 | 95 | printf("Enrollment completed!\n\n"); 96 | return enrolled_print; 97 | } 98 | 99 | int main(void) 100 | { 101 | int r = 1; 102 | struct fp_dscv_dev *ddev; 103 | struct fp_dscv_dev **discovered_devs; 104 | struct fp_dev *dev; 105 | struct fp_print_data *data; 106 | 107 | printf("This program will enroll your right index finger, " 108 | "unconditionally overwriting any right-index print that was enrolled " 109 | "previously. If you want to continue, press enter, otherwise hit " 110 | "Ctrl+C\n"); 111 | getchar(); 112 | 113 | r = fp_init(); 114 | if (r < 0) { 115 | fprintf(stderr, "Failed to initialize libfprint\n"); 116 | exit(1); 117 | } 118 | fp_set_debug(3); 119 | 120 | discovered_devs = fp_discover_devs(); 121 | if (!discovered_devs) { 122 | fprintf(stderr, "Could not discover devices\n"); 123 | goto out; 124 | } 125 | 126 | ddev = discover_device(discovered_devs); 127 | if (!ddev) { 128 | fprintf(stderr, "No devices detected.\n"); 129 | goto out; 130 | } 131 | 132 | dev = fp_dev_open(ddev); 133 | fp_dscv_devs_free(discovered_devs); 134 | if (!dev) { 135 | fprintf(stderr, "Could not open device.\n"); 136 | goto out; 137 | } 138 | 139 | printf("Opened device. It's now time to enroll your finger.\n\n"); 140 | data = enroll(dev); 141 | if (!data) 142 | goto out_close; 143 | 144 | r = fp_print_data_save(data, RIGHT_INDEX); 145 | if (r < 0) 146 | fprintf(stderr, "Data save failed, code %d\n", r); 147 | 148 | fp_print_data_free(data); 149 | out_close: 150 | fp_dev_close(dev); 151 | out: 152 | fp_exit(); 153 | return r; 154 | } 155 | 156 | 157 | -------------------------------------------------------------------------------- /examples/img_capture.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Example libfprint image capture program 3 | * Copyright (C) 2007 Daniel Drake 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | 25 | struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs) 26 | { 27 | struct fp_dscv_dev *ddev = discovered_devs[0]; 28 | struct fp_driver *drv; 29 | if (!ddev) 30 | return NULL; 31 | 32 | drv = fp_dscv_dev_get_driver(ddev); 33 | printf("Found device claimed by %s driver\n", fp_driver_get_full_name(drv)); 34 | return ddev; 35 | } 36 | 37 | int main(void) 38 | { 39 | int r = 1; 40 | struct fp_dscv_dev *ddev; 41 | struct fp_dscv_dev **discovered_devs; 42 | struct fp_dev *dev; 43 | struct fp_img *img = NULL; 44 | 45 | r = fp_init(); 46 | if (r < 0) { 47 | fprintf(stderr, "Failed to initialize libfprint\n"); 48 | exit(1); 49 | } 50 | fp_set_debug(3); 51 | 52 | discovered_devs = fp_discover_devs(); 53 | if (!discovered_devs) { 54 | fprintf(stderr, "Could not discover devices\n"); 55 | goto out; 56 | } 57 | 58 | ddev = discover_device(discovered_devs); 59 | if (!ddev) { 60 | fprintf(stderr, "No devices detected.\n"); 61 | goto out; 62 | } 63 | 64 | dev = fp_dev_open(ddev); 65 | fp_dscv_devs_free(discovered_devs); 66 | if (!dev) { 67 | fprintf(stderr, "Could not open device.\n"); 68 | goto out; 69 | } 70 | 71 | if (!fp_dev_supports_imaging(dev)) { 72 | fprintf(stderr, "this device does not have imaging capabilities.\n"); 73 | goto out_close; 74 | } 75 | 76 | printf("Opened device. It's now time to scan your finger.\n\n"); 77 | 78 | r = fp_dev_img_capture(dev, 0, &img); 79 | if (r) { 80 | fprintf(stderr, "image capture failed, code %d\n", r); 81 | goto out_close; 82 | } 83 | 84 | r = fp_img_save_to_file(img, "finger.pgm"); 85 | if (r) { 86 | fprintf(stderr, "img save failed, code %d\n", r); 87 | goto out_close; 88 | } 89 | 90 | fp_img_standardize(img); 91 | r = fp_img_save_to_file(img, "finger_standardized.pgm"); 92 | fp_img_free(img); 93 | if (r) { 94 | fprintf(stderr, "standardized img save failed, code %d\n", r); 95 | goto out_close; 96 | } 97 | 98 | r = 0; 99 | out_close: 100 | fp_dev_close(dev); 101 | out: 102 | fp_exit(); 103 | return r; 104 | } 105 | 106 | -------------------------------------------------------------------------------- /examples/img_capture_continuous.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Example libfprint continuous image capture program 3 | * Copyright (C) 2007 Daniel Drake 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #define FORMAT 0x32595559 30 | 31 | static int adaptor = -1; 32 | static unsigned char *framebuffer = NULL; 33 | 34 | static Display *display = NULL; 35 | static Window window=(Window)NULL; 36 | static XvImage *xv_image = NULL; 37 | static XvAdaptorInfo *info; 38 | static GC gc; 39 | static int connection = -1; 40 | 41 | /* based on macro by Bart Nabbe */ 42 | #define GREY2YUV(grey, y, u, v)\ 43 | y = (9798*grey + 19235*grey + 3736*grey) / 32768;\ 44 | u = (-4784*grey - 9437*grey + 14221*grey) / 32768 + 128;\ 45 | v = (20218*grey - 16941*grey - 3277*grey) / 32768 + 128;\ 46 | y = y < 0 ? 0 : y;\ 47 | u = u < 0 ? 0 : u;\ 48 | v = v < 0 ? 0 : v;\ 49 | y = y > 255 ? 255 : y;\ 50 | u = u > 255 ? 255 : u;\ 51 | v = v > 255 ? 255 : v 52 | 53 | static void grey2yuy2 (unsigned char *grey, unsigned char *YUV, int num) { 54 | int i, j; 55 | int y0, y1, u0, u1, v0, v1; 56 | int gval; 57 | 58 | for (i = 0, j = 0; i < num; i += 2, j += 4) 59 | { 60 | gval = grey[i]; 61 | GREY2YUV (gval, y0, u0 , v0); 62 | gval = grey[i + 1]; 63 | GREY2YUV (gval, y1, u1 , v1); 64 | YUV[j + 0] = y0; 65 | YUV[j + 1] = (u0+u1)/2; 66 | YUV[j + 2] = y1; 67 | YUV[j + 3] = (v0+v1)/2; 68 | } 69 | } 70 | 71 | static void display_frame(struct fp_img *img) 72 | { 73 | int width = fp_img_get_width(img); 74 | int height = fp_img_get_height(img); 75 | unsigned char *data = fp_img_get_data(img); 76 | 77 | if (adaptor < 0) 78 | return; 79 | 80 | grey2yuy2(data, framebuffer, width * height); 81 | xv_image = XvCreateImage(display, info[adaptor].base_id, FORMAT, 82 | framebuffer, width, height); 83 | XvPutImage(display, info[adaptor].base_id, window, gc, xv_image, 84 | 0, 0, width, height, 0, 0, width, height); 85 | } 86 | 87 | static void QueryXv() 88 | { 89 | int num_adaptors; 90 | int num_formats; 91 | XvImageFormatValues *formats = NULL; 92 | int i,j; 93 | char xv_name[5]; 94 | 95 | XvQueryAdaptors(display, DefaultRootWindow(display), &num_adaptors, 96 | &info); 97 | 98 | for(i = 0; i < num_adaptors; i++) { 99 | formats = XvListImageFormats(display, info[i].base_id, 100 | &num_formats); 101 | for(j = 0; j < num_formats; j++) { 102 | xv_name[4] = 0; 103 | memcpy(xv_name, &formats[j].id, 4); 104 | if(formats[j].id == FORMAT) { 105 | printf("using Xv format 0x%x %s %s\n", 106 | formats[j].id, xv_name, 107 | (formats[j].format==XvPacked) 108 | ? "packed" : "planar"); 109 | if (adaptor < 0) 110 | adaptor = i; 111 | } 112 | } 113 | } 114 | XFree(formats); 115 | if (adaptor < 0) 116 | printf("No suitable Xv adaptor found\n"); 117 | } 118 | 119 | struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs) 120 | { 121 | struct fp_dscv_dev *ddev = discovered_devs[0]; 122 | struct fp_driver *drv; 123 | if (!ddev) 124 | return NULL; 125 | 126 | drv = fp_dscv_dev_get_driver(ddev); 127 | printf("Found device claimed by %s driver\n", fp_driver_get_full_name(drv)); 128 | return ddev; 129 | } 130 | 131 | int main(void) 132 | { 133 | int r = 1; 134 | XEvent xev; 135 | XGCValues xgcv; 136 | long background=0x010203; 137 | struct fp_dscv_dev *ddev; 138 | struct fp_dscv_dev **discovered_devs; 139 | struct fp_dev *dev; 140 | int img_width; 141 | int img_height; 142 | int standardize = 0; 143 | 144 | r = fp_init(); 145 | if (r < 0) { 146 | fprintf(stderr, "Failed to initialize libfprint\n"); 147 | exit(1); 148 | } 149 | fp_set_debug(3); 150 | 151 | discovered_devs = fp_discover_devs(); 152 | if (!discovered_devs) { 153 | fprintf(stderr, "Could not discover devices\n"); 154 | goto out; 155 | } 156 | 157 | ddev = discover_device(discovered_devs); 158 | if (!ddev) { 159 | fprintf(stderr, "No devices detected.\n"); 160 | goto out; 161 | } 162 | 163 | dev = fp_dev_open(ddev); 164 | fp_dscv_devs_free(discovered_devs); 165 | if (!dev) { 166 | fprintf(stderr, "Could not open device.\n"); 167 | goto out; 168 | } 169 | 170 | if (!fp_dev_supports_imaging(dev)) { 171 | fprintf(stderr, "this device does not have imaging capabilities.\n"); 172 | goto out_close; 173 | } 174 | 175 | img_width = fp_dev_get_img_width(dev); 176 | img_height = fp_dev_get_img_height(dev); 177 | if (img_width <= 0 || img_height <= 0) { 178 | fprintf(stderr, "this device returns images with variable dimensions," 179 | " this example does not support that.\n"); 180 | goto out_close; 181 | } 182 | framebuffer = malloc(img_width * img_height * 2); 183 | if (!framebuffer) 184 | goto out_close; 185 | 186 | /* make the window */ 187 | display = XOpenDisplay(getenv("DISPLAY")); 188 | if(display == NULL) { 189 | fprintf(stderr,"Could not open display \"%s\"\n", 190 | getenv("DISPLAY")); 191 | goto out_close; 192 | } 193 | 194 | QueryXv(); 195 | 196 | if (adaptor < 0) 197 | goto out_close; 198 | 199 | window = XCreateSimpleWindow(display, DefaultRootWindow(display), 0, 0, 200 | img_width, img_height, 0, 201 | WhitePixel(display, DefaultScreen(display)), background); 202 | 203 | XSelectInput(display, window, StructureNotifyMask | KeyPressMask); 204 | XMapWindow(display, window); 205 | connection = ConnectionNumber(display); 206 | 207 | gc = XCreateGC(display, window, 0, &xgcv); 208 | 209 | printf("Press S to toggle standardized mode, Q to quit\n"); 210 | 211 | while (1) { /* event loop */ 212 | struct fp_img *img; 213 | 214 | r = fp_dev_img_capture(dev, 1, &img); 215 | if (r) { 216 | fprintf(stderr, "image capture failed, code %d\n", r); 217 | goto out_close; 218 | } 219 | if (standardize) 220 | fp_img_standardize(img); 221 | 222 | display_frame(img); 223 | fp_img_free(img); 224 | XFlush(display); 225 | 226 | while (XPending(display) > 0) { 227 | XNextEvent(display, &xev); 228 | if (xev.type != KeyPress) 229 | continue; 230 | 231 | switch (XKeycodeToKeysym(display, xev.xkey.keycode, 0)) { 232 | case XK_q: 233 | case XK_Q: 234 | r = 0; 235 | goto out_close; 236 | break; 237 | case XK_s: 238 | case XK_S: 239 | standardize = !standardize; 240 | break; 241 | } 242 | } /* XPending */ 243 | } 244 | 245 | r = 0; 246 | out_close: 247 | if (framebuffer) 248 | free(framebuffer); 249 | fp_dev_close(dev); 250 | if ((void *) window != NULL) 251 | XUnmapWindow(display, window); 252 | if (display != NULL) 253 | XFlush(display); 254 | out: 255 | fp_exit(); 256 | return r; 257 | } 258 | 259 | 260 | -------------------------------------------------------------------------------- /examples/verify.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Example fingerprint verification program, which verifies the right index 3 | * finger which has been previously enrolled to disk. 4 | * Copyright (C) 2007 Daniel Drake 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs) 28 | { 29 | struct fp_dscv_dev *ddev = discovered_devs[0]; 30 | struct fp_driver *drv; 31 | if (!ddev) 32 | return NULL; 33 | 34 | drv = fp_dscv_dev_get_driver(ddev); 35 | printf("Found device claimed by %s driver\n", fp_driver_get_full_name(drv)); 36 | return ddev; 37 | } 38 | 39 | int verify(struct fp_dev *dev, struct fp_print_data *data) 40 | { 41 | int r; 42 | 43 | do { 44 | struct fp_img *img = NULL; 45 | 46 | sleep(1); 47 | printf("\nScan your finger now.\n"); 48 | r = fp_verify_finger_img(dev, data, &img); 49 | if (img) { 50 | fp_img_save_to_file(img, "verify.pgm"); 51 | printf("Wrote scanned image to verify.pgm\n"); 52 | fp_img_free(img); 53 | } 54 | if (r < 0) { 55 | printf("verification failed with error %d :(\n", r); 56 | return r; 57 | } 58 | switch (r) { 59 | case FP_VERIFY_NO_MATCH: 60 | printf("NO MATCH!\n"); 61 | return 0; 62 | case FP_VERIFY_MATCH: 63 | printf("MATCH!\n"); 64 | return 0; 65 | case FP_VERIFY_RETRY: 66 | printf("Scan didn't quite work. Please try again.\n"); 67 | break; 68 | case FP_VERIFY_RETRY_TOO_SHORT: 69 | printf("Swipe was too short, please try again.\n"); 70 | break; 71 | case FP_VERIFY_RETRY_CENTER_FINGER: 72 | printf("Please center your finger on the sensor and try again.\n"); 73 | break; 74 | case FP_VERIFY_RETRY_REMOVE_FINGER: 75 | printf("Please remove finger from the sensor and try again.\n"); 76 | break; 77 | } 78 | } while (1); 79 | } 80 | 81 | int main(void) 82 | { 83 | int r = 1; 84 | struct fp_dscv_dev *ddev; 85 | struct fp_dscv_dev **discovered_devs; 86 | struct fp_dev *dev; 87 | struct fp_print_data *data; 88 | 89 | r = fp_init(); 90 | if (r < 0) { 91 | fprintf(stderr, "Failed to initialize libfprint\n"); 92 | exit(1); 93 | } 94 | fp_set_debug(3); 95 | 96 | discovered_devs = fp_discover_devs(); 97 | if (!discovered_devs) { 98 | fprintf(stderr, "Could not discover devices\n"); 99 | goto out; 100 | } 101 | 102 | ddev = discover_device(discovered_devs); 103 | if (!ddev) { 104 | fprintf(stderr, "No devices detected.\n"); 105 | goto out; 106 | } 107 | 108 | dev = fp_dev_open(ddev); 109 | fp_dscv_devs_free(discovered_devs); 110 | if (!dev) { 111 | fprintf(stderr, "Could not open device.\n"); 112 | goto out; 113 | } 114 | 115 | printf("Opened device. Loading previously enrolled right index finger " 116 | "data...\n"); 117 | 118 | r = fp_print_data_load(dev, RIGHT_INDEX, &data); 119 | if (r != 0) { 120 | fprintf(stderr, "Failed to load fingerprint, error %d\n", r); 121 | fprintf(stderr, "Did you remember to enroll your right index finger " 122 | "first?\n"); 123 | goto out_close; 124 | } 125 | 126 | printf("Print loaded. Time to verify!\n"); 127 | do { 128 | char buffer[20]; 129 | 130 | verify(dev, data); 131 | printf("Verify again? [Y/n]? "); 132 | fgets(buffer, sizeof(buffer), stdin); 133 | if (buffer[0] != '\n' && buffer[0] != 'y' && buffer[0] != 'Y') 134 | break; 135 | } while (1); 136 | 137 | fp_print_data_free(data); 138 | out_close: 139 | fp_dev_close(dev); 140 | out: 141 | fp_exit(); 142 | return r; 143 | } 144 | 145 | 146 | -------------------------------------------------------------------------------- /examples/verify_live.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Example fingerprint verification program 3 | * Copyright (C) 2007 Daniel Drake 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | struct fp_dscv_dev *discover_device(struct fp_dscv_dev **discovered_devs) 27 | { 28 | struct fp_dscv_dev *ddev = discovered_devs[0]; 29 | struct fp_driver *drv; 30 | if (!ddev) 31 | return NULL; 32 | 33 | drv = fp_dscv_dev_get_driver(ddev); 34 | printf("Found device claimed by %s driver\n", fp_driver_get_full_name(drv)); 35 | return ddev; 36 | } 37 | 38 | struct fp_print_data *enroll(struct fp_dev *dev) { 39 | struct fp_print_data *enrolled_print = NULL; 40 | int r; 41 | 42 | printf("You will need to successfully scan your finger %d times to " 43 | "complete the process.\n", fp_dev_get_nr_enroll_stages(dev)); 44 | 45 | do { 46 | sleep(1); 47 | printf("\nScan your finger now.\n"); 48 | r = fp_enroll_finger(dev, &enrolled_print); 49 | if (r < 0) { 50 | printf("Enroll failed with error %d\n", r); 51 | return NULL; 52 | } 53 | switch (r) { 54 | case FP_ENROLL_COMPLETE: 55 | printf("Enroll complete!\n"); 56 | break; 57 | case FP_ENROLL_FAIL: 58 | printf("Enroll failed, something wen't wrong :(\n"); 59 | return NULL; 60 | case FP_ENROLL_PASS: 61 | printf("Enroll stage passed. Yay!\n"); 62 | break; 63 | case FP_ENROLL_RETRY: 64 | printf("Didn't quite catch that. Please try again.\n"); 65 | break; 66 | case FP_ENROLL_RETRY_TOO_SHORT: 67 | printf("Your swipe was too short, please try again.\n"); 68 | break; 69 | case FP_ENROLL_RETRY_CENTER_FINGER: 70 | printf("Didn't catch that, please center your finger on the " 71 | "sensor and try again.\n"); 72 | break; 73 | case FP_ENROLL_RETRY_REMOVE_FINGER: 74 | printf("Scan failed, please remove your finger and then try " 75 | "again.\n"); 76 | break; 77 | } 78 | } while (r != FP_ENROLL_COMPLETE); 79 | 80 | if (!enrolled_print) { 81 | fprintf(stderr, "Enroll complete but no print?\n"); 82 | return NULL; 83 | } 84 | 85 | printf("Enrollment completed!\n\n"); 86 | return enrolled_print; 87 | } 88 | 89 | int verify(struct fp_dev *dev, struct fp_print_data *data) 90 | { 91 | int r; 92 | 93 | do { 94 | sleep(1); 95 | printf("\nScan your finger now.\n"); 96 | r = fp_verify_finger(dev, data); 97 | if (r < 0) { 98 | printf("verification failed with error %d :(\n", r); 99 | return r; 100 | } 101 | switch (r) { 102 | case FP_VERIFY_NO_MATCH: 103 | printf("NO MATCH!\n"); 104 | return 0; 105 | case FP_VERIFY_MATCH: 106 | printf("MATCH!\n"); 107 | return 0; 108 | case FP_VERIFY_RETRY: 109 | printf("Scan didn't quite work. Please try again.\n"); 110 | break; 111 | case FP_VERIFY_RETRY_TOO_SHORT: 112 | printf("Swipe was too short, please try again.\n"); 113 | break; 114 | case FP_VERIFY_RETRY_CENTER_FINGER: 115 | printf("Please center your finger on the sensor and try again.\n"); 116 | break; 117 | case FP_VERIFY_RETRY_REMOVE_FINGER: 118 | printf("Please remove finger from the sensor and try again.\n"); 119 | break; 120 | } 121 | } while (1); 122 | } 123 | 124 | int main(void) 125 | { 126 | int r = 1; 127 | struct fp_dscv_dev *ddev; 128 | struct fp_dscv_dev **discovered_devs; 129 | struct fp_dev *dev; 130 | struct fp_print_data *data; 131 | 132 | r = fp_init(); 133 | if (r < 0) { 134 | fprintf(stderr, "Failed to initialize libfprint\n"); 135 | exit(1); 136 | } 137 | fp_set_debug(3); 138 | 139 | discovered_devs = fp_discover_devs(); 140 | if (!discovered_devs) { 141 | fprintf(stderr, "Could not discover devices\n"); 142 | goto out; 143 | } 144 | 145 | ddev = discover_device(discovered_devs); 146 | if (!ddev) { 147 | fprintf(stderr, "No devices detected.\n"); 148 | goto out; 149 | } 150 | 151 | dev = fp_dev_open(ddev); 152 | fp_dscv_devs_free(discovered_devs); 153 | if (!dev) { 154 | fprintf(stderr, "Could not open device.\n"); 155 | goto out; 156 | } 157 | 158 | printf("Opened device. It's now time to enroll your finger.\n\n"); 159 | data = enroll(dev); 160 | if (!data) 161 | goto out_close; 162 | 163 | 164 | printf("Normally we'd save that print to disk, and recall it at some " 165 | "point later when we want to authenticate the user who just " 166 | "enrolled. In the interests of demonstration, we'll authenticate " 167 | "that user immediately.\n"); 168 | 169 | do { 170 | char buffer[20]; 171 | 172 | verify(dev, data); 173 | printf("Verify again? [Y/n]? "); 174 | fgets(buffer, sizeof(buffer), stdin); 175 | if (buffer[0] != '\n' && buffer[0] != 'y' && buffer[0] != 'Y') 176 | break; 177 | } while (1); 178 | 179 | fp_print_data_free(data); 180 | out_close: 181 | fp_dev_close(dev); 182 | out: 183 | fp_exit(); 184 | return r; 185 | } 186 | 187 | 188 | -------------------------------------------------------------------------------- /libfprint.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libfprint 7 | Description: Generic C API for fingerprint reader access 8 | Version: @VERSION@ 9 | Libs: -L${libdir} -lfprint 10 | Cflags: -I${includedir}/libfprint 11 | 12 | -------------------------------------------------------------------------------- /libfprint/Makefile.am: -------------------------------------------------------------------------------- 1 | lib_LTLIBRARIES = libfprint.la 2 | noinst_PROGRAMS = fprint-list-hal-info 3 | MOSTLYCLEANFILES = $(hal_fdi_DATA) 4 | 5 | UPEKTS_SRC = drivers/upekts.c 6 | UPEKTC_SRC = drivers/upektc.c 7 | UPEKSONLY_SRC = drivers/upeksonly.c 8 | URU4000_SRC = drivers/uru4000.c 9 | AES1610_SRC = drivers/aes1610.c 10 | AES2501_SRC = drivers/aes2501.c drivers/aes2501.h 11 | AES4000_SRC = drivers/aes4000.c 12 | FDU2000_SRC = drivers/fdu2000.c 13 | VCOM5S_SRC = drivers/vcom5s.c 14 | 15 | DRIVER_SRC = 16 | OTHER_SRC = 17 | 18 | NBIS_SRC = \ 19 | nbis/include/bozorth.h \ 20 | nbis/include/bz_array.h \ 21 | nbis/include/defs.h \ 22 | nbis/include/lfs.h \ 23 | nbis/include/log.h \ 24 | nbis/include/morph.h \ 25 | nbis/include/sunrast.h \ 26 | nbis/bozorth3/bozorth3.c \ 27 | nbis/bozorth3/bz_alloc.c \ 28 | nbis/bozorth3/bz_drvrs.c \ 29 | nbis/bozorth3/bz_gbls.c \ 30 | nbis/bozorth3/bz_io.c \ 31 | nbis/bozorth3/bz_sort.c \ 32 | nbis/mindtct/binar.c \ 33 | nbis/mindtct/block.c \ 34 | nbis/mindtct/contour.c \ 35 | nbis/mindtct/detect.c \ 36 | nbis/mindtct/dft.c \ 37 | nbis/mindtct/free.c \ 38 | nbis/mindtct/globals.c \ 39 | nbis/mindtct/imgutil.c \ 40 | nbis/mindtct/init.c \ 41 | nbis/mindtct/line.c \ 42 | nbis/mindtct/log.c \ 43 | nbis/mindtct/loop.c \ 44 | nbis/mindtct/maps.c \ 45 | nbis/mindtct/matchpat.c \ 46 | nbis/mindtct/minutia.c \ 47 | nbis/mindtct/morph.c \ 48 | nbis/mindtct/quality.c \ 49 | nbis/mindtct/remove.c \ 50 | nbis/mindtct/ridges.c \ 51 | nbis/mindtct/shape.c \ 52 | nbis/mindtct/sort.c \ 53 | nbis/mindtct/util.c 54 | 55 | libfprint_la_CFLAGS = -fvisibility=hidden -I$(srcdir)/nbis/include $(LIBUSB_CFLAGS) $(GLIB_CFLAGS) $(CRYPTO_CFLAGS) $(AM_CFLAGS) 56 | libfprint_la_LDFLAGS = -version-info @lt_major@:@lt_revision@:@lt_age@ 57 | libfprint_la_LIBADD = -lm $(LIBUSB_LIBS) $(GLIB_LIBS) $(CRYPTO_LIBS) 58 | 59 | fprint_list_hal_info_SOURCES = fprint-list-hal-info.c 60 | fprint_list_hal_info_CFLAGS = -fvisibility=hidden -I$(srcdir)/nbis/include $(LIBUSB_CFLAGS) $(GLIB_CFLAGS) $(IMAGEMAGICK_CFLAGS) $(CRYPTO_CFLAGS) $(AM_CFLAGS) 61 | fprint_list_hal_info_LDADD = $(builddir)/libfprint.la 62 | 63 | hal_fdi_DATA = 10-fingerprint-reader-fprint.fdi 64 | hal_fdidir = $(datadir)/hal/fdi/information/20thirdparty/ 65 | 66 | $(hal_fdi_DATA): fprint-list-hal-info 67 | $(builddir)/fprint-list-hal-info > $@ 68 | 69 | 70 | if ENABLE_UPEKTS 71 | DRIVER_SRC += $(UPEKTS_SRC) 72 | endif 73 | 74 | if ENABLE_UPEKSONLY 75 | DRIVER_SRC += $(UPEKSONLY_SRC) 76 | endif 77 | 78 | #if ENABLE_UPEKTC 79 | #DRIVER_SRC += $(UPEKTC_SRC) 80 | #endif 81 | 82 | if ENABLE_URU4000 83 | DRIVER_SRC += $(URU4000_SRC) 84 | endif 85 | 86 | if ENABLE_VCOM5S 87 | DRIVER_SRC += $(VCOM5S_SRC) 88 | endif 89 | 90 | #if ENABLE_FDU2000 91 | #DRIVER_SRC += $(FDU2000_SRC) 92 | #endif 93 | 94 | #if ENABLE_AES1610 95 | #DRIVER_SRC += $(AES1610_SRC) 96 | #endif 97 | 98 | if ENABLE_AES2501 99 | DRIVER_SRC += $(AES2501_SRC) 100 | endif 101 | 102 | if ENABLE_AES4000 103 | DRIVER_SRC += $(AES4000_SRC) 104 | endif 105 | 106 | if REQUIRE_IMAGEMAGICK 107 | OTHER_SRC += imagemagick.c 108 | libfprint_la_CFLAGS += $(IMAGEMAGICK_CFLAGS) 109 | libfprint_la_LIBADD += $(IMAGEMAGICK_LIBS) 110 | endif 111 | 112 | if REQUIRE_AESLIB 113 | OTHER_SRC += aeslib.c aeslib.h 114 | endif 115 | 116 | libfprint_la_SOURCES = \ 117 | fp_internal.h \ 118 | async.c \ 119 | core.c \ 120 | data.c \ 121 | drv.c \ 122 | img.c \ 123 | imgdev.c \ 124 | poll.c \ 125 | sync.c \ 126 | $(DRIVER_SRC) \ 127 | $(OTHER_SRC) \ 128 | $(NBIS_SRC) 129 | 130 | pkginclude_HEADERS = fprint.h 131 | -------------------------------------------------------------------------------- /libfprint/aeslib.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Shared functions between libfprint Authentec drivers 3 | * Copyright (C) 2007-2008 Daniel Drake 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #define FP_COMPONENT "aeslib" 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | #include "fp_internal.h" 28 | #include "aeslib.h" 29 | 30 | #define MAX_REGWRITES_PER_REQUEST 16 31 | 32 | #define BULK_TIMEOUT 4000 33 | #define EP_IN (1 | LIBUSB_ENDPOINT_IN) 34 | #define EP_OUT (2 | LIBUSB_ENDPOINT_OUT) 35 | 36 | struct write_regv_data { 37 | struct fp_img_dev *imgdev; 38 | unsigned int num_regs; 39 | const struct aes_regwrite *regs; 40 | unsigned int offset; 41 | aes_write_regv_cb callback; 42 | void *user_data; 43 | }; 44 | 45 | static void continue_write_regv(struct write_regv_data *wdata); 46 | 47 | /* libusb bulk callback for regv write completion transfer. continues the 48 | * transaction */ 49 | static void write_regv_trf_complete(struct libusb_transfer *transfer) 50 | { 51 | struct write_regv_data *wdata = transfer->user_data; 52 | 53 | if (transfer->status != LIBUSB_TRANSFER_COMPLETED) 54 | wdata->callback(wdata->imgdev, -EIO, wdata->user_data); 55 | else if (transfer->length != transfer->actual_length) 56 | wdata->callback(wdata->imgdev, -EPROTO, wdata->user_data); 57 | else 58 | continue_write_regv(wdata); 59 | 60 | g_free(transfer->buffer); 61 | libusb_free_transfer(transfer); 62 | } 63 | 64 | /* write from wdata->offset to upper_bound (inclusive) of wdata->regs */ 65 | static int do_write_regv(struct write_regv_data *wdata, int upper_bound) 66 | { 67 | unsigned int offset = wdata->offset; 68 | unsigned int num = upper_bound - offset + 1; 69 | size_t alloc_size = num * 2; 70 | unsigned char *data = g_malloc(alloc_size); 71 | unsigned int i; 72 | size_t data_offset = 0; 73 | struct libusb_transfer *transfer = libusb_alloc_transfer(0); 74 | int r; 75 | 76 | if (!transfer) { 77 | g_free(data); 78 | return -ENOMEM; 79 | } 80 | 81 | for (i = offset; i < offset + num; i++) { 82 | const struct aes_regwrite *regwrite = &wdata->regs[i]; 83 | data[data_offset++] = regwrite->reg; 84 | data[data_offset++] = regwrite->value; 85 | } 86 | 87 | libusb_fill_bulk_transfer(transfer, wdata->imgdev->udev, EP_OUT, data, 88 | alloc_size, write_regv_trf_complete, wdata, BULK_TIMEOUT); 89 | r = libusb_submit_transfer(transfer); 90 | if (r < 0) { 91 | g_free(data); 92 | libusb_free_transfer(transfer); 93 | } 94 | 95 | return r; 96 | } 97 | 98 | /* write the next batch of registers to be written, or if there are no more, 99 | * indicate completion to the caller */ 100 | static void continue_write_regv(struct write_regv_data *wdata) 101 | { 102 | unsigned int offset = wdata->offset; 103 | unsigned int regs_remaining; 104 | unsigned int limit; 105 | unsigned int upper_bound; 106 | int i; 107 | int r; 108 | 109 | /* skip all zeros and ensure there is still work to do */ 110 | while (TRUE) { 111 | if (offset >= wdata->num_regs) { 112 | fp_dbg("all registers written"); 113 | wdata->callback(wdata->imgdev, 0, wdata->user_data); 114 | return; 115 | } 116 | if (wdata->regs[offset].reg) 117 | break; 118 | offset++; 119 | } 120 | 121 | wdata->offset = offset; 122 | regs_remaining = wdata->num_regs - offset; 123 | limit = MIN(regs_remaining, MAX_REGWRITES_PER_REQUEST); 124 | upper_bound = offset + limit - 1; 125 | 126 | /* determine if we can write the entire of the regs at once, or if there 127 | * is a zero dividing things up */ 128 | for (i = offset; i <= upper_bound; i++) 129 | if (!wdata->regs[i].reg) { 130 | upper_bound = i - 1; 131 | break; 132 | } 133 | 134 | r = do_write_regv(wdata, upper_bound); 135 | if (r < 0) { 136 | wdata->callback(wdata->imgdev, r, wdata->user_data); 137 | return; 138 | } 139 | 140 | wdata->offset = upper_bound + 1; 141 | } 142 | 143 | /* write a load of registers to the device, combining multiple writes in a 144 | * single URB up to a limit. insert writes to non-existent register 0 to force 145 | * specific groups of writes to be separated by different URBs. */ 146 | void aes_write_regv(struct fp_img_dev *dev, const struct aes_regwrite *regs, 147 | unsigned int num_regs, aes_write_regv_cb callback, void *user_data) 148 | { 149 | struct write_regv_data *wdata = g_malloc(sizeof(*wdata)); 150 | fp_dbg("write %d regs", num_regs); 151 | wdata->imgdev = dev; 152 | wdata->num_regs = num_regs; 153 | wdata->regs = regs; 154 | wdata->offset = 0; 155 | wdata->callback = callback; 156 | wdata->user_data = user_data; 157 | continue_write_regv(wdata); 158 | } 159 | 160 | void aes_assemble_image(unsigned char *input, size_t width, size_t height, 161 | unsigned char *output) 162 | { 163 | size_t row, column; 164 | 165 | for (column = 0; column < width; column++) { 166 | for (row = 0; row < height; row += 2) { 167 | output[width * row + column] = (*input & 0x07) * 36; 168 | output[width * (row + 1) + column] = ((*input & 0x70) >> 4) * 36; 169 | input++; 170 | } 171 | } 172 | } 173 | 174 | -------------------------------------------------------------------------------- /libfprint/aeslib.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Shared functions between libfprint Authentec drivers 3 | * Copyright (C) 2007 Daniel Drake 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef __AESLIB_H__ 21 | #define __AESLIB_H__ 22 | 23 | #include 24 | 25 | struct aes_regwrite { 26 | unsigned char reg; 27 | unsigned char value; 28 | }; 29 | 30 | typedef void (*aes_write_regv_cb)(struct fp_img_dev *dev, int result, 31 | void *user_data); 32 | 33 | void aes_write_regv(struct fp_img_dev *dev, const struct aes_regwrite *regs, 34 | unsigned int num_regs, aes_write_regv_cb callback, void *user_data); 35 | 36 | void aes_assemble_image(unsigned char *input, size_t width, size_t height, 37 | unsigned char *output); 38 | 39 | #endif 40 | 41 | -------------------------------------------------------------------------------- /libfprint/drivers/aes2501.h: -------------------------------------------------------------------------------- 1 | /* 2 | * AuthenTec AES2501 driver for libfprint 3 | * Copyright (C) 2007 Cyrille Bagard 4 | * 5 | * Based on code from http://home.gna.org/aes2501, relicensed with permission 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Lesser General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2.1 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Lesser General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public 18 | * License along with this library; if not, write to the Free Software 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | */ 21 | 22 | #ifndef __AES2501_H 23 | #define __AES2501_H 24 | 25 | enum aes2501_regs { 26 | AES2501_REG_CTRL1 = 0x80, 27 | AES2501_REG_CTRL2 = 0x81, 28 | AES2501_REG_EXCITCTRL = 0x82, /* excitation control */ 29 | AES2501_REG_DETCTRL = 0x83, /* detect control */ 30 | AES2501_REG_COLSCAN = 0x88, /* column scan rate register */ 31 | AES2501_REG_MEASDRV = 0x89, /* measure drive */ 32 | AES2501_REG_MEASFREQ = 0x8a, /* measure frequency */ 33 | AES2501_REG_DEMODPHASE1 = 0x8d, 34 | AES2501_REG_DEMODPHASE2 = 0x8c, 35 | AES2501_REG_CHANGAIN = 0x8e, /* channel gain */ 36 | AES2501_REG_ADREFHI = 0x91, /* A/D reference high */ 37 | AES2501_REG_ADREFLO = 0x92, /* A/D reference low */ 38 | AES2501_REG_STRTROW = 0x93, /* start row */ 39 | AES2501_REG_ENDROW = 0x94, /* end row */ 40 | AES2501_REG_STRTCOL = 0x95, /* start column */ 41 | AES2501_REG_ENDCOL = 0x96, /* end column */ 42 | AES2501_REG_DATFMT = 0x97, /* data format */ 43 | AES2501_REG_IMAGCTRL = 0x98, /* image data */ 44 | AES2501_REG_STAT = 0x9a, 45 | AES2501_REG_CHWORD1 = 0x9b, /* challenge word 1 */ 46 | AES2501_REG_CHWORD2 = 0x9c, 47 | AES2501_REG_CHWORD3 = 0x9d, 48 | AES2501_REG_CHWORD4 = 0x9e, 49 | AES2501_REG_CHWORD5 = 0x9f, 50 | AES2501_REG_TREG1 = 0xa1, /* test register 1 */ 51 | AES2501_REG_AUTOCALOFFSET = 0xa8, 52 | AES2501_REG_TREGC = 0xac, 53 | AES2501_REG_TREGD = 0xad, 54 | AES2501_REG_LPONT = 0xb4, /* low power oscillator on time */ 55 | }; 56 | 57 | #define FIRST_AES2501_REG AES2501_REG_CTRL1 58 | #define LAST_AES2501_REG AES2501_REG_CHWORD5 59 | 60 | #define AES2501_CTRL1_MASTER_RESET (1<<0) 61 | #define AES2501_CTRL1_SCAN_RESET (1<<1) /* stop + restart scan sequencer */ 62 | /* 1 = continuously updated, 0 = updated prior to starting a scan */ 63 | #define AES2501_CTRL1_REG_UPDATE (1<<2) 64 | 65 | /* 1 = continuous scans, 0 = single scans */ 66 | #define AES2501_CTRL2_CONTINUOUS 0x01 67 | #define AES2501_CTRL2_READ_REGS 0x02 /* dump registers */ 68 | #define AES2501_CTRL2_SET_ONE_SHOT 0x04 69 | #define AES2501_CTRL2_CLR_ONE_SHOT 0x08 70 | #define AES2501_CTRL2_READ_ID 0x10 71 | 72 | enum aes2501_detection_rate { 73 | /* rate of detection cycles: */ 74 | AES2501_DETCTRL_DRATE_CONTINUOUS = 0x00, /* continuously */ 75 | AES2501_DETCTRL_DRATE_16_MS = 0x01, /* every 16.62ms */ 76 | AES2501_DETCTRL_DRATE_31_MS = 0x02, /* every 31.24ms */ 77 | AES2501_DETCTRL_DRATE_62_MS = 0x03, /* every 62.50ms */ 78 | AES2501_DETCTRL_DRATE_125_MS = 0x04, /* every 125.0ms */ 79 | AES2501_DETCTRL_DRATE_250_MS = 0x05, /* every 250.0ms */ 80 | AES2501_DETCTRL_DRATE_500_MS = 0x06, /* every 500.0ms */ 81 | AES2501_DETCTRL_DRATE_1_S = 0x07, /* every 1s */ 82 | }; 83 | 84 | enum aes2501_settling_delay { 85 | AES2501_DETCTRL_SDELAY_31_MS = 0x00, /* 31.25ms */ 86 | AES2501_DETCTRL_SSDELAY_62_MS = 0x10, /* 62.5ms */ 87 | AES2501_DETCTRL_SSDELAY_125_MS = 0x20, /* 125ms */ 88 | AES2501_DETCTRL_SSDELAY_250_MS = 0x30 /* 250ms */ 89 | }; 90 | 91 | enum aes2501_col_scan_rate { 92 | AES2501_COLSCAN_SRATE_32_US = 0x00, /* 32us */ 93 | AES2501_COLSCAN_SRATE_64_US = 0x01, /* 64us */ 94 | AES2501_COLSCAN_SRATE_128_US = 0x02, /* 128us */ 95 | AES2501_COLSCAN_SRATE_256_US = 0x03, /* 256us */ 96 | AES2501_COLSCAN_SRATE_512_US = 0x04, /* 512us */ 97 | AES2501_COLSCAN_SRATE_1024_US = 0x05, /* 1024us */ 98 | AES2501_COLSCAN_SRATE_2048_US = 0x06, /* 2048us */ 99 | 100 | }; 101 | 102 | enum aes2501_mesure_drive { 103 | AES2501_MEASDRV_MDRIVE_0_325 = 0x00, /* 0.325 Vpp */ 104 | AES2501_MEASDRV_MDRIVE_0_65 = 0x01, /* 0.65 Vpp */ 105 | AES2501_MEASDRV_MDRIVE_1_3 = 0x02, /* 1.3 Vpp */ 106 | AES2501_MEASDRV_MDRIVE_2_6 = 0x03 /* 2.6 Vpp */ 107 | 108 | }; 109 | 110 | /* Select (1=square | 0=sine) wave drive during measure */ 111 | #define AES2501_MEASDRV_SQUARE 0x20 112 | /* 0 = use mesure drive setting, 1 = when sine wave is selected */ 113 | #define AES2501_MEASDRV_MEASURE_SQUARE 0x10 114 | 115 | enum aes2501_measure_freq { 116 | AES2501_MEASFREQ_125K = 0x01, /* 125 kHz */ 117 | AES2501_MEASFREQ_250K = 0x02, /* 250 kHz */ 118 | AES2501_MEASFREQ_500K = 0x03, /* 500 kHz */ 119 | AES2501_MEASFREQ_1M = 0x04, /* 1 MHz */ 120 | AES2501_MEASFREQ_2M = 0x05 /* 2 MHz */ 121 | }; 122 | 123 | #define DEMODPHASE_NONE 0x00 124 | #define DEMODPHASE_180_00 0x40 /* 180 degrees */ 125 | #define DEMODPHASE_2_81 0x01 /* 2.8125 degrees */ 126 | 127 | #define AES2501_REG_DEMODPHASE1 0x8d 128 | #define DEMODPHASE_1_40 0x40 /* 1.40625 degrees */ 129 | #define DEMODPHASE_0_02 0x01 /* 0.02197256 degrees */ 130 | 131 | enum aes2501_sensor_gain1 { 132 | AES2501_CHANGAIN_STAGE1_2X = 0x00, /* 2x */ 133 | AES2501_CHANGAIN_STAGE1_4X = 0x01, /* 4x */ 134 | AES2501_CHANGAIN_STAGE1_8X = 0x02, /* 8x */ 135 | AES2501_CHANGAIN_STAGE1_16X = 0x03 /* 16x */ 136 | }; 137 | 138 | enum aes2501_sensor_gain2 { 139 | AES2501_CHANGAIN_STAGE2_2X = 0x00, /* 2x */ 140 | AES2501_CHANGAIN_STAGE2_4X = 0x10, /* 4x */ 141 | AES2501_CHANGAIN_STAGE2_8X = 0x20, /* 8x */ 142 | AES2501_CHANGAIN_STAGE2_16X = 0x30 /* 16x */ 143 | }; 144 | 145 | #define AES2501_DATFMT_EIGHT 0x40 /* 1 = 8-bit data, 0 = 4-bit data */ 146 | #define AES2501_DATFMT_LOW_RES 0x20 147 | #define AES2501_DATFMT_BIN_IMG 0x10 148 | 149 | /* don't send image or authentication messages when imaging */ 150 | #define AES2501_IMAGCTRL_IMG_DATA_DISABLE 0x01 151 | /* send histogram when imaging */ 152 | #define AES2501_IMAGCTRL_HISTO_DATA_ENABLE 0x02 153 | /* send histogram at end of each row rather than each scan */ 154 | #define AES2501_IMAGCTRL_HISTO_EACH_ROW 0x04 155 | /* send full image array rather than 64x64 center */ 156 | #define AES2501_IMAGCTRL_HISTO_FULL_ARRAY 0x08 157 | /* return registers before data (rather than after) */ 158 | #define AES2501_IMAGCTRL_REG_FIRST 0x10 159 | /* return test registers with register dump */ 160 | #define AES2501_IMAGCTRL_TST_REG_ENABLE 0x20 161 | 162 | #define AES2501_CHWORD1_IS_FINGER 0x01 /* If set, finger is present */ 163 | 164 | /* Enable the reading of the register in TREGD */ 165 | #define AES2501_TREGC_ENABLE 0x01 166 | 167 | #define AES2501_LPONT_MIN_VALUE 0x00 /* 0 ms */ 168 | #define AES2501_LPONT_MAX_VALUE 0x1f /* About 16 ms */ 169 | 170 | #endif /* __AES2501_H */ 171 | -------------------------------------------------------------------------------- /libfprint/drivers/aes4000.c: -------------------------------------------------------------------------------- 1 | /* 2 | * AuthenTec AES4000 driver for libfprint 3 | * Copyright (C) 2007-2008 Daniel Drake 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #define FP_COMPONENT "aes4000" 21 | 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | #define CTRL_TIMEOUT 1000 31 | #define EP_IN (1 | LIBUSB_ENDPOINT_IN) 32 | #define EP_OUT (2 | LIBUSB_ENDPOINT_OUT) 33 | #define DATA_BUFLEN 0x1259 34 | #define NR_SUBARRAYS 6 35 | #define SUBARRAY_LEN 768 36 | 37 | #define IMG_HEIGHT 96 38 | #define IMG_WIDTH 96 39 | #define ENLARGE_FACTOR 3 40 | 41 | struct aes4k_dev { 42 | struct libusb_transfer *img_trf; 43 | }; 44 | 45 | static const struct aes_regwrite init_reqs[] = { 46 | /* master reset */ 47 | { 0x80, 0x01 }, 48 | { 0, 0 }, 49 | { 0x80, 0x00 }, 50 | { 0, 0 }, 51 | 52 | { 0x81, 0x00 }, 53 | { 0x80, 0x00 }, 54 | { 0, 0 }, 55 | 56 | /* scan reset */ 57 | { 0x80, 0x02 }, 58 | { 0, 0 }, 59 | { 0x80, 0x00 }, 60 | { 0, 0 }, 61 | 62 | /* disable register buffering */ 63 | { 0x80, 0x04 }, 64 | { 0, 0 }, 65 | { 0x80, 0x00 }, 66 | { 0, 0 }, 67 | 68 | { 0x81, 0x00 }, 69 | { 0, 0 }, 70 | /* windows driver reads registers now (81 02) */ 71 | { 0x80, 0x00 }, 72 | { 0x81, 0x00 }, 73 | 74 | /* set excitation bias current: 2mhz drive ring frequency, 75 | * 4V drive ring voltage, 16.5mA excitation bias */ 76 | { 0x82, 0x04 }, 77 | 78 | /* continuously sample drive ring for finger detection, 79 | * 62.50ms debounce delay */ 80 | { 0x83, 0x13 }, 81 | 82 | { 0x84, 0x07 }, /* set calibration resistance to 12 kiloohms */ 83 | { 0x85, 0x3d }, /* set calibration capacitance */ 84 | { 0x86, 0x03 }, /* detect drive voltage */ 85 | { 0x87, 0x01 }, /* set detection frequency to 125khz */ 86 | { 0x88, 0x02 }, /* set column scan period */ 87 | { 0x89, 0x02 }, /* set measure drive */ 88 | { 0x8a, 0x33 }, /* set measure frequency and sense amplifier bias */ 89 | { 0x8b, 0x33 }, /* set matrix pattern */ 90 | { 0x8c, 0x0f }, /* set demodulation phase 1 */ 91 | { 0x8d, 0x04 }, /* set demodulation phase 2 */ 92 | { 0x8e, 0x23 }, /* set sensor gain */ 93 | { 0x8f, 0x07 }, /* set image parameters */ 94 | { 0x90, 0x00 }, /* carrier offset null */ 95 | { 0x91, 0x1c }, /* set A/D reference high */ 96 | { 0x92, 0x08 }, /* set A/D reference low */ 97 | { 0x93, 0x00 }, /* set start row to 0 */ 98 | { 0x94, 0x05 }, /* set end row to 5 */ 99 | { 0x95, 0x00 }, /* set start column to 0 */ 100 | { 0x96, 0x18 }, /* set end column to 24*4=96 */ 101 | { 0x97, 0x04 }, /* data format and thresholds */ 102 | { 0x98, 0x28 }, /* image data control */ 103 | { 0x99, 0x00 }, /* disable general purpose outputs */ 104 | { 0x9a, 0x0b }, /* set initial scan state */ 105 | { 0x9b, 0x00 }, /* clear challenge word bits */ 106 | { 0x9c, 0x00 }, /* clear challenge word bits */ 107 | { 0x9d, 0x09 }, /* set some challenge word bits */ 108 | { 0x9e, 0x53 }, /* clear challenge word bits */ 109 | { 0x9f, 0x6b }, /* set some challenge word bits */ 110 | { 0, 0 }, 111 | 112 | { 0x80, 0x00 }, 113 | { 0x81, 0x00 }, 114 | { 0, 0 }, 115 | { 0x81, 0x04 }, 116 | { 0, 0 }, 117 | { 0x81, 0x00 }, 118 | }; 119 | 120 | static void do_capture(struct fp_img_dev *dev); 121 | 122 | static void img_cb(struct libusb_transfer *transfer) 123 | { 124 | struct fp_img_dev *dev = transfer->user_data; 125 | struct aes4k_dev *aesdev = dev->priv; 126 | unsigned char *ptr = transfer->buffer; 127 | struct fp_img *tmp; 128 | struct fp_img *img; 129 | int i; 130 | 131 | if (transfer->status == LIBUSB_TRANSFER_CANCELLED) { 132 | goto err; 133 | } else if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { 134 | fpi_imgdev_session_error(dev, -EIO); 135 | goto err; 136 | } else if (transfer->length != transfer->actual_length) { 137 | fpi_imgdev_session_error(dev, -EPROTO); 138 | goto err; 139 | } 140 | 141 | fpi_imgdev_report_finger_status(dev, TRUE); 142 | 143 | tmp = fpi_img_new(IMG_WIDTH * IMG_HEIGHT); 144 | tmp->width = IMG_WIDTH; 145 | tmp->height = IMG_HEIGHT; 146 | tmp->flags = FP_IMG_COLORS_INVERTED | FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED; 147 | for (i = 0; i < NR_SUBARRAYS; i++) { 148 | fp_dbg("subarray header byte %02x", *ptr); 149 | ptr++; 150 | aes_assemble_image(ptr, 96, 16, tmp->data + (i * 96 * 16)); 151 | ptr += SUBARRAY_LEN; 152 | } 153 | 154 | /* FIXME: this is an ugly hack to make the image big enough for NBIS 155 | * to process reliably */ 156 | img = fpi_im_resize(tmp, ENLARGE_FACTOR); 157 | fp_img_free(tmp); 158 | fpi_imgdev_image_captured(dev, img); 159 | 160 | /* FIXME: rather than assuming finger has gone, we should poll regs until 161 | * it really has, then restart the capture */ 162 | fpi_imgdev_report_finger_status(dev, FALSE); 163 | 164 | do_capture(dev); 165 | 166 | err: 167 | g_free(transfer->buffer); 168 | aesdev->img_trf = NULL; 169 | libusb_free_transfer(transfer); 170 | } 171 | 172 | static void do_capture(struct fp_img_dev *dev) 173 | { 174 | struct aes4k_dev *aesdev = dev->priv; 175 | unsigned char *data; 176 | int r; 177 | 178 | aesdev->img_trf = libusb_alloc_transfer(0); 179 | if (!aesdev->img_trf) { 180 | fpi_imgdev_session_error(dev, -EIO); 181 | return; 182 | } 183 | 184 | data = g_malloc(DATA_BUFLEN); 185 | libusb_fill_bulk_transfer(aesdev->img_trf, dev->udev, EP_IN, data, 186 | DATA_BUFLEN, img_cb, dev, 0); 187 | 188 | r = libusb_submit_transfer(aesdev->img_trf); 189 | if (r < 0) { 190 | g_free(data); 191 | libusb_free_transfer(aesdev->img_trf); 192 | aesdev->img_trf = NULL; 193 | fpi_imgdev_session_error(dev, r); 194 | } 195 | } 196 | 197 | static void init_reqs_cb(struct fp_img_dev *dev, int result, void *user_data) 198 | { 199 | fpi_imgdev_activate_complete(dev, result); 200 | if (result == 0) 201 | do_capture(dev); 202 | } 203 | 204 | static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) 205 | { 206 | aes_write_regv(dev, init_reqs, G_N_ELEMENTS(init_reqs), init_reqs_cb, NULL); 207 | return 0; 208 | } 209 | 210 | static void dev_deactivate(struct fp_img_dev *dev) 211 | { 212 | struct aes4k_dev *aesdev = dev->priv; 213 | 214 | /* FIXME: should wait for cancellation to complete before returning 215 | * from deactivation, otherwise app may legally exit before we've 216 | * cleaned up */ 217 | if (aesdev->img_trf) 218 | libusb_cancel_transfer(aesdev->img_trf); 219 | fpi_imgdev_deactivate_complete(dev); 220 | } 221 | 222 | static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) 223 | { 224 | int r; 225 | 226 | r = libusb_claim_interface(dev->udev, 0); 227 | if (r < 0) 228 | fp_err("could not claim interface 0"); 229 | 230 | dev->priv = g_malloc0(sizeof(struct aes4k_dev)); 231 | 232 | if (r == 0) 233 | fpi_imgdev_open_complete(dev, 0); 234 | 235 | return r; 236 | } 237 | 238 | static void dev_deinit(struct fp_img_dev *dev) 239 | { 240 | g_free(dev->priv); 241 | libusb_release_interface(dev->udev, 0); 242 | fpi_imgdev_close_complete(dev); 243 | } 244 | 245 | static const struct usb_id id_table[] = { 246 | { .vendor = 0x08ff, .product = 0x5501 }, 247 | { 0, 0, 0, }, 248 | }; 249 | 250 | struct fp_img_driver aes4000_driver = { 251 | .driver = { 252 | .id = 3, 253 | .name = FP_COMPONENT, 254 | .full_name = "AuthenTec AES4000", 255 | .id_table = id_table, 256 | .scan_type = FP_SCAN_TYPE_PRESS, 257 | }, 258 | .flags = 0, 259 | .img_height = IMG_HEIGHT * ENLARGE_FACTOR, 260 | .img_width = IMG_WIDTH * ENLARGE_FACTOR, 261 | 262 | /* temporarily lowered until image quality improves */ 263 | .bz3_threshold = 9, 264 | 265 | .open = dev_init, 266 | .close = dev_deinit, 267 | .activate = dev_activate, 268 | .deactivate = dev_deactivate, 269 | }; 270 | 271 | -------------------------------------------------------------------------------- /libfprint/drivers/fdu2000.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Secugen FDU2000 driver for libfprint 3 | * Copyright (C) 2007 Gustavo Chain 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #define FP_COMPONENT "fdu2000" 27 | #include 28 | 29 | #ifndef HAVE_MEMMEM 30 | gpointer 31 | memmem(const gpointer haystack, size_t haystack_len, const gpointer needle, size_t needle_len) { 32 | const gchar *begin; 33 | const char *const last_possible = (const char *) haystack + haystack_len - needle_len; 34 | 35 | /* The first occurrence of the empty string is deemed to occur at 36 | * the beginning of the string. */ 37 | if (needle_len == 0) 38 | return (void *) haystack; 39 | 40 | /* Sanity check, otherwise the loop might search through the whole 41 | * memory. */ 42 | if (haystack_len < needle_len) 43 | return NULL; 44 | 45 | for (begin = (const char *) haystack; begin <= last_possible; ++begin) 46 | if (begin[0] == ((const char *) needle)[0] && 47 | !memcmp((const void *) &begin[1], 48 | (const void *) ((const char *) needle + 1), 49 | needle_len - 1)) 50 | return (void *) begin; 51 | 52 | return NULL; 53 | } 54 | #endif /* HAVE_MEMMEM */ 55 | 56 | #define EP_IMAGE ( 0x02 | LIBUSB_ENDPOINT_IN ) 57 | #define EP_REPLY ( 0x01 | LIBUSB_ENDPOINT_IN ) 58 | #define EP_CMD ( 0x01 | LIBUSB_ENDPOINT_OUT ) 59 | #define BULK_TIMEOUT 200 60 | 61 | /* fdu_req[] index */ 62 | typedef enum { 63 | CAPTURE_READY, 64 | CAPTURE_READ, 65 | CAPTURE_END, 66 | LED_OFF, 67 | LED_ON 68 | } req_index; 69 | 70 | 71 | #define CMD_LEN 2 72 | #define ACK_LEN 8 73 | static const struct fdu2000_req { 74 | const gchar cmd[CMD_LEN]; // Command to send 75 | const gchar ack[ACK_LEN]; // Expected ACK 76 | const guint ack_len; // ACK has variable length 77 | } fdu_req[] = { 78 | /* Capture */ 79 | { 80 | .cmd = { 0x00, 0x04 }, 81 | .ack = { 0x00, 0x04, 0x01, 0x01 }, 82 | .ack_len = 4 83 | }, 84 | 85 | { 86 | .cmd = { 0x00, 0x01 }, 87 | .ack = { 0x00, 0x01, 0x01, 0x01 }, 88 | .ack_len = 4 89 | }, 90 | 91 | { 92 | .cmd = { 0x00, 0x05 }, 93 | .ack = { 0x00, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, 94 | .ack_len = 8 95 | }, 96 | 97 | /* Led */ 98 | { 99 | .cmd = { 0x05, 0x00 }, 100 | .ack = {}, 101 | .ack_len = 0 102 | }, 103 | 104 | { 105 | .cmd = { 0x05, 0x01 }, 106 | .ack = {}, 107 | .ack_len = 0 108 | } 109 | }; 110 | 111 | /* 112 | * Write a command and verify reponse 113 | */ 114 | static gint 115 | bulk_write_safe(libusb_dev_handle *dev, req_index rIndex) { 116 | 117 | gchar reponse[ACK_LEN]; 118 | gint r; 119 | gchar *cmd = (gchar *)fdu_req[rIndex].cmd; 120 | gchar *ack = (gchar *)fdu_req[rIndex].ack; 121 | gint ack_len = fdu_req[rIndex].ack_len; 122 | struct libusb_bulk_transfer wrmsg = { 123 | .endpoint = EP_CMD, 124 | .data = cmd, 125 | .length = sizeof(cmd), 126 | }; 127 | struct libusb_bulk_transfer readmsg = { 128 | .endpoint = EP_REPLY, 129 | .data = reponse, 130 | .length = sizeof(reponse), 131 | }; 132 | int trf; 133 | 134 | r = libusb_bulk_transfer(dev, &wrmsg, &trf, BULK_TIMEOUT); 135 | if (r < 0) 136 | return r; 137 | 138 | if (ack_len == 0) 139 | return 0; 140 | 141 | /* Check reply from FP */ 142 | r = libusb_bulk_transfer(dev, &readmsg, &trf, BULK_TIMEOUT); 143 | if (r < 0) 144 | return r; 145 | 146 | if (!strncmp(ack, reponse, ack_len)) 147 | return 0; 148 | 149 | fp_err("Expected different ACK from dev"); 150 | return 1; /* Error */ 151 | } 152 | 153 | static gint 154 | capture(struct fp_img_dev *dev, gboolean unconditional, 155 | struct fp_img **ret) 156 | { 157 | #define RAW_IMAGE_WIDTH 398 158 | #define RAW_IMAGE_HEIGTH 301 159 | #define RAW_IMAGE_SIZE (RAW_IMAGE_WIDTH * RAW_IMAGE_HEIGTH) 160 | 161 | struct fp_img *img = NULL; 162 | int bytes, r; 163 | const gchar SOF[] = { 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x0c, 0x07 }; // Start of frame 164 | const gchar SOL[] = { 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x0b, 0x06 }; // Start of line + { L L } (L: Line num) (8 nibbles) 165 | gchar *buffer = g_malloc0(RAW_IMAGE_SIZE * 6); 166 | gchar *image; 167 | gchar *p; 168 | guint offset; 169 | struct libusb_bulk_transfer msg = { 170 | .endpoint = EP_IMAGE, 171 | .data = buffer, 172 | .length = RAW_IMAGE_SIZE * 6, 173 | }; 174 | 175 | image = g_malloc0(RAW_IMAGE_SIZE); 176 | 177 | if ((r = bulk_write_safe(dev->udev, LED_ON))) { 178 | fp_err("Command: LED_ON"); 179 | goto out; 180 | } 181 | 182 | if ((r = bulk_write_safe(dev->udev, CAPTURE_READY))) { 183 | fp_err("Command: CAPTURE_READY"); 184 | goto out; 185 | } 186 | 187 | read: 188 | if ((r = bulk_write_safe(dev->udev, CAPTURE_READ))) { 189 | fp_err("Command: CAPTURE_READ"); 190 | goto out; 191 | } 192 | 193 | /* Now we are ready to read from dev */ 194 | 195 | r = libusb_bulk_transfer(dev->udev, &msg, &bytes, BULK_TIMEOUT * 10); 196 | if (r < 0 || bytes < 1) 197 | goto read; 198 | 199 | /* 200 | * Find SOF (start of line) 201 | */ 202 | p = memmem(buffer, RAW_IMAGE_SIZE * 6, 203 | (const gpointer)SOF, sizeof SOF); 204 | fp_dbg("Read %d byte/s from dev", bytes); 205 | if (!p) 206 | goto out; 207 | 208 | p += sizeof SOF; 209 | 210 | int i = 0; 211 | bytes = 0; 212 | while(p) { 213 | if ( i >= RAW_IMAGE_HEIGTH ) 214 | break; 215 | 216 | offset = p - buffer; 217 | p = memmem(p, (RAW_IMAGE_SIZE * 6) - (offset), 218 | (const gpointer)SOL, sizeof SOL); 219 | if (p) { 220 | p += sizeof SOL + 4; 221 | int j; 222 | for (j = 0; j < RAW_IMAGE_WIDTH; j++) { 223 | /** 224 | * Convert from 4 to 8 bits 225 | * The SECUGEN-FDU2000 has 4 lines of data, so we need to join 2 bytes into 1 226 | */ 227 | *(image + bytes + j) = *(p + (j * 2) + 0) << 4 & 0xf0; 228 | *(image + bytes + j) |= *(p + (j * 2) + 1) & 0x0f; 229 | } 230 | p += RAW_IMAGE_WIDTH * 2; 231 | bytes += RAW_IMAGE_WIDTH; 232 | i++; 233 | } 234 | } 235 | 236 | if ((r = bulk_write_safe(dev->udev, CAPTURE_END))) { 237 | fp_err("Command: CAPTURE_END"); 238 | goto out; 239 | } 240 | 241 | if ((r = bulk_write_safe(dev->udev, LED_OFF))) { 242 | fp_err("Command: LED_OFF"); 243 | goto out; 244 | } 245 | 246 | img = fpi_img_new_for_imgdev(dev); 247 | memcpy(img->data, image, RAW_IMAGE_SIZE); 248 | img->flags = FP_IMG_COLORS_INVERTED | FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED; 249 | *ret = img; 250 | 251 | out: 252 | g_free(buffer); 253 | g_free(image); 254 | 255 | return r; 256 | } 257 | 258 | static 259 | gint dev_init(struct fp_img_dev *dev, unsigned long driver_data) 260 | { 261 | gint r; 262 | //if ( (r = usb_set_configuration(dev->udev, 1)) < 0 ) 263 | // goto out; 264 | 265 | if ( (r = libusb_claim_interface(dev->udev, 0)) < 0 ) 266 | goto out; 267 | 268 | //if ( (r = usb_set_altinterface(dev->udev, 1)) < 0 ) 269 | // goto out; 270 | 271 | //if ( (r = usb_clear_halt(dev->udev, EP_CMD)) < 0 ) 272 | // goto out; 273 | 274 | /* Make sure sensor mode is not capture_{ready|read} */ 275 | if ((r = bulk_write_safe(dev->udev, CAPTURE_END))) { 276 | fp_err("Command: CAPTURE_END"); 277 | goto out; 278 | } 279 | 280 | if ((r = bulk_write_safe(dev->udev, LED_OFF))) { 281 | fp_err("Command: LED_OFF"); 282 | goto out; 283 | } 284 | 285 | return 0; 286 | 287 | out: 288 | fp_err("could not init dev"); 289 | return r; 290 | } 291 | 292 | static 293 | void dev_exit(struct fp_img_dev *dev) 294 | { 295 | if (bulk_write_safe(dev->udev, CAPTURE_END)) 296 | fp_err("Command: CAPTURE_END"); 297 | 298 | libusb_release_interface(dev->udev, 0); 299 | } 300 | 301 | static const struct usb_id id_table[] = { 302 | { .vendor = 0x1162, .product = 0x0300 }, 303 | { 0, 0, 0, }, 304 | }; 305 | 306 | struct fp_img_driver fdu2000_driver = { 307 | .driver = { 308 | .id = 7, 309 | .name = FP_COMPONENT, 310 | .full_name = "Secugen FDU 2000", 311 | .id_table = id_table, 312 | .scan_type = FP_SCAN_TYPE_PRESS, 313 | }, 314 | .img_height = RAW_IMAGE_HEIGTH, 315 | .img_width = RAW_IMAGE_WIDTH, 316 | .bz3_threshold = 23, 317 | 318 | .init = dev_init, 319 | .exit = dev_exit, 320 | .capture = capture, 321 | }; 322 | -------------------------------------------------------------------------------- /libfprint/drivers/vcom5s.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Veridicom 5thSense driver for libfprint 3 | * Copyright (C) 2008 Daniel Drake 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #define FP_COMPONENT "vcom5s" 21 | 22 | /* TODO: 23 | * calibration? 24 | * image size: windows gets 300x300 through vpas enrollment util? 25 | * (probably just increase bulk read size?) 26 | * powerdown? does windows do anything special on exit? 27 | */ 28 | 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | #define CTRL_IN 0xc0 38 | #define CTRL_OUT 0x40 39 | #define CTRL_TIMEOUT 1000 40 | #define EP_IN (1 | LIBUSB_ENDPOINT_IN) 41 | 42 | #define IMG_WIDTH 300 43 | #define IMG_HEIGHT 288 44 | #define ROWS_PER_RQ 12 45 | #define NR_REQS (IMG_HEIGHT / ROWS_PER_RQ) 46 | #define RQ_SIZE (IMG_WIDTH * ROWS_PER_RQ) 47 | #define IMG_SIZE (IMG_WIDTH * IMG_HEIGHT) 48 | 49 | struct v5s_dev { 50 | int capture_iteration; 51 | struct fp_img *capture_img; 52 | gboolean loop_running; 53 | gboolean deactivating; 54 | }; 55 | 56 | enum v5s_regs { 57 | /* when using gain 0x29: 58 | * a value of 0x00 produces mostly-black image 59 | * 0x09 destroys ridges (too white) 60 | * 0x01 or 0x02 seem good values */ 61 | REG_CONTRAST = 0x02, 62 | 63 | /* when using contrast 0x01: 64 | * a value of 0x00 will produce an all-black image. 65 | * 0x29 produces a good contrast image: ridges quite dark, but some 66 | * light grey noise as background 67 | * 0x46 produces all-white image with grey ridges (not very dark) */ 68 | REG_GAIN = 0x03, 69 | }; 70 | 71 | enum v5s_cmd { 72 | /* scan one row. has parameter, at a guess this is which row to scan? */ 73 | CMD_SCAN_ONE_ROW = 0xc0, 74 | 75 | /* scan whole image */ 76 | CMD_SCAN = 0xc1, 77 | }; 78 | 79 | /***** REGISTER I/O *****/ 80 | 81 | static void sm_write_reg_cb(struct libusb_transfer *transfer) 82 | { 83 | struct fpi_ssm *ssm = transfer->user_data; 84 | 85 | if (transfer->status != LIBUSB_TRANSFER_COMPLETED) 86 | fpi_ssm_mark_aborted(ssm, -EIO); 87 | else 88 | fpi_ssm_next_state(ssm); 89 | 90 | g_free(transfer->buffer); 91 | libusb_free_transfer(transfer); 92 | } 93 | 94 | static void sm_write_reg(struct fpi_ssm *ssm, unsigned char reg, 95 | unsigned char value) 96 | { 97 | struct fp_img_dev *dev = ssm->priv; 98 | struct libusb_transfer *transfer = libusb_alloc_transfer(0); 99 | unsigned char *data; 100 | int r; 101 | 102 | if (!transfer) { 103 | fpi_ssm_mark_aborted(ssm, -ENOMEM); 104 | return; 105 | } 106 | 107 | fp_dbg("set %02x=%02x", reg, value); 108 | data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE); 109 | libusb_fill_control_setup(data, CTRL_OUT, reg, value, 0, 0); 110 | libusb_fill_control_transfer(transfer, dev->udev, data, sm_write_reg_cb, 111 | ssm, CTRL_TIMEOUT); 112 | r = libusb_submit_transfer(transfer); 113 | if (r < 0) { 114 | g_free(data); 115 | libusb_free_transfer(transfer); 116 | fpi_ssm_mark_aborted(ssm, r); 117 | } 118 | } 119 | 120 | static void sm_exec_cmd_cb(struct libusb_transfer *transfer) 121 | { 122 | struct fpi_ssm *ssm = transfer->user_data; 123 | 124 | if (transfer->status != LIBUSB_TRANSFER_COMPLETED) 125 | fpi_ssm_mark_aborted(ssm, -EIO); 126 | else 127 | fpi_ssm_next_state(ssm); 128 | 129 | g_free(transfer->buffer); 130 | libusb_free_transfer(transfer); 131 | } 132 | 133 | static void sm_exec_cmd(struct fpi_ssm *ssm, unsigned char cmd, 134 | unsigned char param) 135 | { 136 | struct fp_img_dev *dev = ssm->priv; 137 | struct libusb_transfer *transfer = libusb_alloc_transfer(0); 138 | unsigned char *data; 139 | int r; 140 | 141 | if (!transfer) { 142 | fpi_ssm_mark_aborted(ssm, -ENOMEM); 143 | return; 144 | } 145 | 146 | fp_dbg("cmd %02x param %02x", cmd, param); 147 | data = g_malloc(LIBUSB_CONTROL_SETUP_SIZE); 148 | libusb_fill_control_setup(data, CTRL_IN, cmd, param, 0, 0); 149 | libusb_fill_control_transfer(transfer, dev->udev, data, sm_exec_cmd_cb, 150 | ssm, CTRL_TIMEOUT); 151 | r = libusb_submit_transfer(transfer); 152 | if (r < 0) { 153 | g_free(data); 154 | libusb_free_transfer(transfer); 155 | fpi_ssm_mark_aborted(ssm, r); 156 | } 157 | } 158 | 159 | /***** FINGER DETECTION *****/ 160 | 161 | /* We take 64x64 pixels at the center of the image, determine the average 162 | * pixel intensity, and threshold it. */ 163 | #define DETBOX_ROW_START 111 164 | #define DETBOX_COL_START 117 165 | #define DETBOX_ROWS 64 166 | #define DETBOX_COLS 64 167 | #define DETBOX_ROW_END (DETBOX_ROW_START + DETBOX_ROWS) 168 | #define DETBOX_COL_END (DETBOX_COL_START + DETBOX_COLS) 169 | #define FINGER_PRESENCE_THRESHOLD 100 170 | 171 | static gboolean finger_is_present(unsigned char *data) 172 | { 173 | int row; 174 | uint16_t imgavg = 0; 175 | 176 | for (row = DETBOX_ROW_START; row < DETBOX_ROW_END; row++) { 177 | unsigned char *rowdata = data + (row * IMG_WIDTH); 178 | uint16_t rowavg = 0; 179 | int col; 180 | 181 | for (col = DETBOX_COL_START; col < DETBOX_COL_END; col++) 182 | rowavg += rowdata[col]; 183 | rowavg /= DETBOX_COLS; 184 | imgavg += rowavg; 185 | } 186 | imgavg /= DETBOX_ROWS; 187 | fp_dbg("img avg %d", imgavg); 188 | 189 | return (imgavg <= FINGER_PRESENCE_THRESHOLD); 190 | } 191 | 192 | 193 | 194 | /***** IMAGE ACQUISITION *****/ 195 | 196 | static void capture_iterate(struct fpi_ssm *ssm); 197 | 198 | static void capture_cb(struct libusb_transfer *transfer) 199 | { 200 | struct fpi_ssm *ssm = transfer->user_data; 201 | struct fp_img_dev *dev = ssm->priv; 202 | struct v5s_dev *vdev = dev->priv; 203 | 204 | if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { 205 | fpi_ssm_mark_aborted(ssm, -EIO); 206 | goto out; 207 | } 208 | 209 | if (++vdev->capture_iteration == NR_REQS) { 210 | struct fp_img *img = vdev->capture_img; 211 | /* must clear this early, otherwise the call chain takes us into 212 | * loopsm_complete where we would free it, when in fact we are 213 | * supposed to be handing off this image */ 214 | vdev->capture_img = NULL; 215 | 216 | fpi_imgdev_report_finger_status(dev, finger_is_present(img->data)); 217 | fpi_imgdev_image_captured(dev, img); 218 | fpi_ssm_next_state(ssm); 219 | } else { 220 | capture_iterate(ssm); 221 | } 222 | 223 | out: 224 | libusb_free_transfer(transfer); 225 | } 226 | 227 | static void capture_iterate(struct fpi_ssm *ssm) 228 | { 229 | struct fp_img_dev *dev = ssm->priv; 230 | struct v5s_dev *vdev = dev->priv; 231 | int iteration = vdev->capture_iteration; 232 | struct libusb_transfer *transfer = libusb_alloc_transfer(0); 233 | int r; 234 | 235 | if (!transfer) { 236 | fpi_ssm_mark_aborted(ssm, -ENOMEM); 237 | return; 238 | } 239 | 240 | libusb_fill_bulk_transfer(transfer, dev->udev, EP_IN, 241 | vdev->capture_img->data + (RQ_SIZE * iteration), RQ_SIZE, 242 | capture_cb, ssm, CTRL_TIMEOUT); 243 | transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK; 244 | r = libusb_submit_transfer(transfer); 245 | if (r < 0) { 246 | libusb_free_transfer(transfer); 247 | fpi_ssm_mark_aborted(ssm, r); 248 | } 249 | } 250 | 251 | 252 | static void sm_do_capture(struct fpi_ssm *ssm) 253 | { 254 | struct fp_img_dev *dev = ssm->priv; 255 | struct v5s_dev *vdev = dev->priv; 256 | 257 | fp_dbg(""); 258 | vdev->capture_img = fpi_img_new_for_imgdev(dev); 259 | vdev->capture_iteration = 0; 260 | capture_iterate(ssm); 261 | } 262 | 263 | /***** CAPTURE LOOP *****/ 264 | 265 | enum loop_states { 266 | LOOP_SET_CONTRAST, 267 | LOOP_SET_GAIN, 268 | LOOP_CMD_SCAN, 269 | LOOP_CAPTURE, 270 | LOOP_CAPTURE_DONE, 271 | LOOP_NUM_STATES, 272 | }; 273 | 274 | static void loop_run_state(struct fpi_ssm *ssm) 275 | { 276 | struct fp_img_dev *dev = ssm->priv; 277 | struct v5s_dev *vdev = dev->priv; 278 | 279 | switch (ssm->cur_state) { 280 | case LOOP_SET_CONTRAST: 281 | sm_write_reg(ssm, REG_CONTRAST, 0x01); 282 | break; 283 | case LOOP_SET_GAIN: 284 | sm_write_reg(ssm, REG_GAIN, 0x29); 285 | break; 286 | case LOOP_CMD_SCAN: 287 | if (vdev->deactivating) { 288 | fp_dbg("deactivating, marking completed"); 289 | fpi_ssm_mark_completed(ssm); 290 | } else 291 | sm_exec_cmd(ssm, CMD_SCAN, 0x00); 292 | break; 293 | case LOOP_CAPTURE: 294 | sm_do_capture(ssm); 295 | break; 296 | case LOOP_CAPTURE_DONE: 297 | fpi_ssm_jump_to_state(ssm, LOOP_CMD_SCAN); 298 | break; 299 | } 300 | } 301 | 302 | static void loopsm_complete(struct fpi_ssm *ssm) 303 | { 304 | struct fp_img_dev *dev = ssm->priv; 305 | struct v5s_dev *vdev = dev->priv; 306 | int r = ssm->error; 307 | 308 | fpi_ssm_free(ssm); 309 | fp_img_free(vdev->capture_img); 310 | vdev->capture_img = NULL; 311 | vdev->loop_running = FALSE; 312 | 313 | if (r) 314 | fpi_imgdev_session_error(dev, r); 315 | 316 | if (vdev->deactivating) 317 | fpi_imgdev_deactivate_complete(dev); 318 | } 319 | 320 | static int dev_activate(struct fp_img_dev *dev, enum fp_imgdev_state state) 321 | { 322 | struct v5s_dev *vdev = dev->priv; 323 | struct fpi_ssm *ssm = fpi_ssm_new(dev->dev, loop_run_state, 324 | LOOP_NUM_STATES); 325 | ssm->priv = dev; 326 | vdev->deactivating = FALSE; 327 | fpi_ssm_start(ssm, loopsm_complete); 328 | vdev->loop_running = TRUE; 329 | fpi_imgdev_activate_complete(dev, 0); 330 | return 0; 331 | } 332 | 333 | static void dev_deactivate(struct fp_img_dev *dev) 334 | { 335 | struct v5s_dev *vdev = dev->priv; 336 | if (vdev->loop_running) 337 | vdev->deactivating = TRUE; 338 | else 339 | fpi_imgdev_deactivate_complete(dev); 340 | } 341 | 342 | static int dev_init(struct fp_img_dev *dev, unsigned long driver_data) 343 | { 344 | int r; 345 | dev->priv = g_malloc0(sizeof(struct v5s_dev)); 346 | 347 | r = libusb_claim_interface(dev->udev, 0); 348 | if (r < 0) 349 | fp_err("could not claim interface 0"); 350 | 351 | if (r == 0) 352 | fpi_imgdev_open_complete(dev, 0); 353 | 354 | return r; 355 | } 356 | 357 | static void dev_deinit(struct fp_img_dev *dev) 358 | { 359 | g_free(dev->priv); 360 | libusb_release_interface(dev->udev, 0); 361 | fpi_imgdev_close_complete(dev); 362 | } 363 | 364 | static const struct usb_id id_table[] = { 365 | { .vendor = 0x061a, .product = 0x0110 }, 366 | { 0, 0, 0, }, 367 | }; 368 | 369 | struct fp_img_driver vcom5s_driver = { 370 | .driver = { 371 | .id = 8, 372 | .name = FP_COMPONENT, 373 | .full_name = "Veridicom 5thSense", 374 | .id_table = id_table, 375 | .scan_type = FP_SCAN_TYPE_PRESS, 376 | }, 377 | .flags = 0, 378 | .img_height = IMG_HEIGHT, 379 | .img_width = IMG_WIDTH, 380 | 381 | .open = dev_init, 382 | .close = dev_deinit, 383 | .activate = dev_activate, 384 | .deactivate = dev_deactivate, 385 | }; 386 | 387 | -------------------------------------------------------------------------------- /libfprint/drv.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Functions to assist with asynchronous driver <---> library communications 3 | * Copyright (C) 2007-2008 Daniel Drake 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #define FP_COMPONENT "drv" 21 | 22 | #include 23 | #include 24 | 25 | #include "fp_internal.h" 26 | 27 | /* SSM: sequential state machine 28 | * Asynchronous driver design encourages some kind of state machine behind it. 29 | * In most cases, the state machine is entirely linear - you only go to the 30 | * next state, you never jump or go backwards. The SSM functions help you 31 | * implement such a machine. 32 | * 33 | * e.g. S1 --> S2 --> S3 --> S4 34 | * S1 is the start state 35 | * There is also an implicit error state and an implicit accepting state 36 | * (both with implicit edges from every state). 37 | * 38 | * You can also jump to any arbitrary state (while marking completion of the 39 | * current state) while the machine is running. In other words there are 40 | * implicit edges linking one state to every other state. OK, we're stretching 41 | * the "state machine" description at this point. 42 | * 43 | * To create a ssm, you pass a state handler function and the total number of 44 | * states (4 in the above example). 45 | * 46 | * To start a ssm, you pass in a completion callback function which gets 47 | * called when the ssm completes (both on error and on failure). 48 | * 49 | * To iterate to the next state, call fpi_ssm_next_state(). It is legal to 50 | * attempt to iterate beyond the final state - this is equivalent to marking 51 | * the ssm as successfully completed. 52 | * 53 | * To mark successful completion of a SSM, either iterate beyond the final 54 | * state or call fpi_ssm_mark_completed() from any state. 55 | * 56 | * To mark failed completion of a SSM, call fpi_ssm_mark_aborted() from any 57 | * state. You must pass a non-zero error code. 58 | * 59 | * Your state handling function looks at ssm->cur_state in order to determine 60 | * the current state and hence which operations to perform (a switch statement 61 | * is appropriate). 62 | * Typically, the state handling function fires off an asynchronous libusb 63 | * transfer, and the callback function iterates the machine to the next state 64 | * upon success (or aborts the machine on transfer failure). 65 | * 66 | * Your completion callback should examine ssm->error in order to determine 67 | * whether the ssm completed or failed. An error code of zero indicates 68 | * successful completion. 69 | */ 70 | 71 | /* Allocate a new ssm */ 72 | struct fpi_ssm *fpi_ssm_new(struct fp_dev *dev, ssm_handler_fn handler, 73 | int nr_states) 74 | { 75 | struct fpi_ssm *machine; 76 | BUG_ON(nr_states < 1); 77 | 78 | machine = g_malloc0(sizeof(*machine)); 79 | machine->handler = handler; 80 | machine->nr_states = nr_states; 81 | machine->dev = dev; 82 | machine->completed = TRUE; 83 | return machine; 84 | } 85 | 86 | /* Free a ssm */ 87 | void fpi_ssm_free(struct fpi_ssm *machine) 88 | { 89 | if (!machine) 90 | return; 91 | g_free(machine); 92 | } 93 | 94 | /* Invoke the state handler */ 95 | static void __ssm_call_handler(struct fpi_ssm *machine) 96 | { 97 | fp_dbg("%p entering state %d", machine, machine->cur_state); 98 | machine->handler(machine); 99 | } 100 | 101 | /* Start a ssm. You can also restart a completed or aborted ssm. */ 102 | void fpi_ssm_start(struct fpi_ssm *ssm, ssm_completed_fn callback) 103 | { 104 | BUG_ON(!ssm->completed); 105 | ssm->callback = callback; 106 | ssm->cur_state = 0; 107 | ssm->completed = FALSE; 108 | ssm->error = 0; 109 | __ssm_call_handler(ssm); 110 | } 111 | 112 | static void __subsm_complete(struct fpi_ssm *ssm) 113 | { 114 | struct fpi_ssm *parent = ssm->parentsm; 115 | BUG_ON(!parent); 116 | if (ssm->error) 117 | fpi_ssm_mark_aborted(parent, ssm->error); 118 | else 119 | fpi_ssm_next_state(parent); 120 | fpi_ssm_free(ssm); 121 | } 122 | 123 | /* start a SSM as a child of another. if the child completes successfully, the 124 | * parent will be advanced to the next state. if the child aborts, the parent 125 | * will be aborted with the same error code. the child will be automatically 126 | * freed upon completion/abortion. */ 127 | void fpi_ssm_start_subsm(struct fpi_ssm *parent, struct fpi_ssm *child) 128 | { 129 | child->parentsm = parent; 130 | fpi_ssm_start(child, __subsm_complete); 131 | } 132 | 133 | /* Mark a ssm as completed successfully. */ 134 | void fpi_ssm_mark_completed(struct fpi_ssm *machine) 135 | { 136 | BUG_ON(machine->completed); 137 | machine->completed = TRUE; 138 | fp_dbg("%p completed with status %d", machine, machine->error); 139 | if (machine->callback) 140 | machine->callback(machine); 141 | } 142 | 143 | /* Mark a ssm as aborted with error. */ 144 | void fpi_ssm_mark_aborted(struct fpi_ssm *machine, int error) 145 | { 146 | fp_dbg("error %d from state %d", error, machine->cur_state); 147 | BUG_ON(error == 0); 148 | machine->error = error; 149 | fpi_ssm_mark_completed(machine); 150 | } 151 | 152 | /* Iterate to next state of a ssm */ 153 | void fpi_ssm_next_state(struct fpi_ssm *machine) 154 | { 155 | BUG_ON(machine->completed); 156 | machine->cur_state++; 157 | if (machine->cur_state == machine->nr_states) { 158 | fpi_ssm_mark_completed(machine); 159 | } else { 160 | __ssm_call_handler(machine); 161 | } 162 | } 163 | 164 | void fpi_ssm_jump_to_state(struct fpi_ssm *machine, int state) 165 | { 166 | BUG_ON(machine->completed); 167 | BUG_ON(state >= machine->nr_states); 168 | machine->cur_state = state; 169 | __ssm_call_handler(machine); 170 | } 171 | 172 | -------------------------------------------------------------------------------- /libfprint/fprint-list-hal-info.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Helper binary for creating a HAL FDI file for supported devices 3 | * Copyright (C) 2008 Bastien Nocera 4 | * Copyright (C) 2008 Timo Hoenig , 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include 22 | #include 23 | 24 | #include "fp_internal.h" 25 | 26 | /* FDI entry example: 27 | * 28 | * 29 | * 30 | * 31 | * biometric.fingerprint_reader 32 | * libfprint 33 | * biometric 34 | * biometric.fingerprint_reader 35 | * aes2501 36 | * true 37 | * 38 | * 39 | * 40 | */ 41 | 42 | static void print_driver (struct fp_driver *driver) 43 | { 44 | int i; 45 | 46 | for (i = 0; driver->id_table[i].vendor != 0; i++) { 47 | printf (" \n", fp_driver_get_full_name (driver)); 48 | printf (" \n", driver->id_table[i].vendor); 49 | printf (" \n", driver->id_table[i].product); 50 | printf (" biometric.fingerprint_reader\n"); 51 | printf (" libfprint\n"); 52 | printf (" biometric\n"); 53 | printf (" biometric.fingerprint_reader\n"); 54 | printf (" %s\n", driver->name); 55 | printf (" true\n"); 56 | printf (" %s\n", 57 | fp_driver_get_scan_type (driver) == FP_SCAN_TYPE_PRESS ? "press" : "swipe"); 58 | printf (" \n"); 59 | printf (" \n"); 60 | } 61 | } 62 | 63 | int main (int argc, char **argv) 64 | { 65 | struct fp_driver **list; 66 | guint i; 67 | 68 | list = fprint_get_drivers (); 69 | 70 | printf ("\n"); 71 | printf ("\n", VERSION); 72 | printf ("\n"); 73 | 74 | for (i = 0; list[i] != NULL; i++) { 75 | print_driver (list[i]); 76 | } 77 | 78 | printf ("\n"); 79 | 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /libfprint/imagemagick.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Imaging utility functions for libfprint 3 | * Copyright (C) 2007-2008 Daniel Drake 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #include "fp_internal.h" 24 | 25 | struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int factor) 26 | { 27 | Image *mimg; 28 | Image *resized; 29 | ExceptionInfo exception; 30 | MagickBooleanType ret; 31 | int new_width = img->width * factor; 32 | int new_height = img->height * factor; 33 | struct fp_img *newimg; 34 | 35 | /* It is possible to implement resizing using a simple algorithm, however 36 | * we use ImageMagick because it applies some kind of smoothing to the 37 | * result, which improves matching performances in my experiments. */ 38 | 39 | if (!IsMagickInstantiated()) 40 | InitializeMagick(NULL); 41 | 42 | GetExceptionInfo(&exception); 43 | mimg = ConstituteImage(img->width, img->height, "I", CharPixel, img->data, 44 | &exception); 45 | 46 | GetExceptionInfo(&exception); 47 | resized = ResizeImage(mimg, new_width, new_height, 0, 1.0, &exception); 48 | 49 | newimg = fpi_img_new(new_width * new_height); 50 | newimg->width = new_width; 51 | newimg->height = new_height; 52 | newimg->flags = img->flags; 53 | 54 | GetExceptionInfo(&exception); 55 | ret = ExportImagePixels(resized, 0, 0, new_width, new_height, "I", 56 | CharPixel, newimg->data, &exception); 57 | if (ret != MagickTrue) { 58 | fp_err("export failed"); 59 | return NULL; 60 | } 61 | 62 | DestroyImage(mimg); 63 | DestroyImage(resized); 64 | 65 | return newimg; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /libfprint/nbis/bozorth3/bz_alloc.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | 3 | This file is part of the Export Control subset of the United States NIST 4 | Biometric Image Software (NBIS) distribution: 5 | http://fingerprint.nist.gov/NBIS/index.html 6 | 7 | It is our understanding that this falls within ECCN 3D980, which covers 8 | software associated with the development, production or use of certain 9 | equipment controlled in accordance with U.S. concerns about crime control 10 | practices in specific countries. 11 | 12 | Therefore, this file should not be exported, or made available on fileservers, 13 | except as allowed by U.S. export control laws. 14 | 15 | Do not remove this notice. 16 | 17 | ******************************************************************************/ 18 | 19 | /* NOTE: Despite the above notice (which I have not removed), this file is 20 | * being legally distributed within libfprint; the U.S. Export Administration 21 | * Regulations do not place export restrictions upon distribution of 22 | * "publicly available technology and software", as stated in EAR section 23 | * 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per 24 | * the definition in section 734.7(a)(1). 25 | * 26 | * For further information, see http://reactivated.net/fprint/US_export_control 27 | */ 28 | 29 | /******************************************************************************* 30 | 31 | License: 32 | This software was developed at the National Institute of Standards and 33 | Technology (NIST) by employees of the Federal Government in the course 34 | of their official duties. Pursuant to title 17 Section 105 of the 35 | United States Code, this software is not subject to copyright protection 36 | and is in the public domain. NIST assumes no responsibility whatsoever for 37 | its use by other parties, and makes no guarantees, expressed or implied, 38 | about its quality, reliability, or any other characteristic. 39 | 40 | Disclaimer: 41 | This software was developed to promote biometric standards and biometric 42 | technology testing for the Federal Government in accordance with the USA 43 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 44 | Specific hardware and software products identified in this software were used 45 | in order to perform the software development. In no case does such 46 | identification imply recommendation or endorsement by the National Institute 47 | of Standards and Technology, nor does it imply that the products and equipment 48 | identified are necessarily the best available for the purpose. 49 | 50 | *******************************************************************************/ 51 | 52 | /*********************************************************************** 53 | LIBRARY: FING - NIST Fingerprint Systems Utilities 54 | 55 | FILE: BZ_ALLOC.C 56 | ALGORITHM: Allan S. Bozorth (FBI) 57 | MODIFICATIONS: Michael D. Garris (NIST) 58 | Stan Janet (NIST) 59 | DATE: 09/21/2004 60 | 61 | Contains routines responsible for supporting the 62 | Bozorth3 fingerprint matching algorithm. 63 | 64 | *********************************************************************** 65 | 66 | ROUTINES: 67 | #cat: malloc_or_exit - allocates a buffer of bytes from the heap of 68 | #cat: specified length exiting directly upon system error 69 | #cat: malloc_or_return_error - allocates a buffer of bytes from the heap 70 | #cat: of specified length returning an error code upon system error 71 | 72 | ***********************************************************************/ 73 | 74 | #include 75 | #include 76 | #include 77 | 78 | 79 | /***********************************************************************/ 80 | char * malloc_or_exit( int nbytes, const char * what ) 81 | { 82 | char * p; 83 | 84 | /* These are now externally defined in bozorth.h */ 85 | /* extern FILE * stderr; */ 86 | /* extern char * get_progname( void ); */ 87 | 88 | 89 | p = malloc( (size_t) nbytes ); 90 | if ( p == CNULL ) { 91 | fprintf( stderr, "%s: ERROR: malloc() of %d bytes for %s failed: %s\n", 92 | get_progname(), 93 | nbytes, 94 | what, 95 | strerror( errno ) 96 | ); 97 | exit(1); 98 | } 99 | return p; 100 | } 101 | 102 | /***********************************************************************/ 103 | /* returns CNULL on error */ 104 | char * malloc_or_return_error( int nbytes, const char * what ) 105 | { 106 | char * p; 107 | 108 | p = malloc( (size_t) nbytes ); 109 | if ( p == CNULL ) { 110 | fprintf( stderr, "%s: ERROR: malloc() of %d bytes for %s failed: %s\n", 111 | get_progname(), 112 | nbytes, 113 | what, 114 | strerror( errno ) 115 | ); 116 | return(CNULL); 117 | } 118 | return p; 119 | } 120 | -------------------------------------------------------------------------------- /libfprint/nbis/bozorth3/bz_drvrs.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | 3 | This file is part of the Export Control subset of the United States NIST 4 | Biometric Image Software (NBIS) distribution: 5 | http://fingerprint.nist.gov/NBIS/index.html 6 | 7 | It is our understanding that this falls within ECCN 3D980, which covers 8 | software associated with the development, production or use of certain 9 | equipment controlled in accordance with U.S. concerns about crime control 10 | practices in specific countries. 11 | 12 | Therefore, this file should not be exported, or made available on fileservers, 13 | except as allowed by U.S. export control laws. 14 | 15 | Do not remove this notice. 16 | 17 | ******************************************************************************/ 18 | 19 | /* NOTE: Despite the above notice (which I have not removed), this file is 20 | * being legally distributed within libfprint; the U.S. Export Administration 21 | * Regulations do not place export restrictions upon distribution of 22 | * "publicly available technology and software", as stated in EAR section 23 | * 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per 24 | * the definition in section 734.7(a)(1). 25 | * 26 | * For further information, see http://reactivated.net/fprint/US_export_control 27 | */ 28 | 29 | /******************************************************************************* 30 | 31 | License: 32 | This software was developed at the National Institute of Standards and 33 | Technology (NIST) by employees of the Federal Government in the course 34 | of their official duties. Pursuant to title 17 Section 105 of the 35 | United States Code, this software is not subject to copyright protection 36 | and is in the public domain. NIST assumes no responsibility whatsoever for 37 | its use by other parties, and makes no guarantees, expressed or implied, 38 | about its quality, reliability, or any other characteristic. 39 | 40 | Disclaimer: 41 | This software was developed to promote biometric standards and biometric 42 | technology testing for the Federal Government in accordance with the USA 43 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 44 | Specific hardware and software products identified in this software were used 45 | in order to perform the software development. In no case does such 46 | identification imply recommendation or endorsement by the National Institute 47 | of Standards and Technology, nor does it imply that the products and equipment 48 | identified are necessarily the best available for the purpose. 49 | 50 | *******************************************************************************/ 51 | 52 | /*********************************************************************** 53 | LIBRARY: FING - NIST Fingerprint Systems Utilities 54 | 55 | FILE: BZ_DRVRS.C 56 | ALGORITHM: Allan S. Bozorth (FBI) 57 | MODIFICATIONS: Michael D. Garris (NIST) 58 | Stan Janet (NIST) 59 | DATE: 09/21/2004 60 | 61 | Contains driver routines responsible for kicking off matches 62 | using the Bozorth3 fingerprint matching algorithm. 63 | 64 | *********************************************************************** 65 | 66 | ROUTINES: 67 | #cat: bozorth_probe_init - creates the pairwise minutia comparison 68 | #cat: table for the probe fingerprint 69 | #cat: bozorth_gallery_init - creates the pairwise minutia comparison 70 | #cat: table for the gallery fingerprint 71 | #cat: bozorth_to_gallery - supports the matching scenario where the 72 | #cat: same probe fingerprint is matches repeatedly 73 | #cat: to multiple gallery fingerprints as in 74 | #cat: identification mode 75 | #cat: bozorth_main - supports the matching scenario where a 76 | #cat: single probe fingerprint is to be matched 77 | #cat: to a single gallery fingerprint as in 78 | #cat: verificaiton mode 79 | 80 | ***********************************************************************/ 81 | 82 | #include 83 | #include 84 | #include 85 | #include 86 | 87 | /**************************************************************************/ 88 | 89 | int bozorth_probe_init( struct xyt_struct * pstruct ) 90 | { 91 | int sim; /* number of pointwise comparisons for Subject's record*/ 92 | int msim; /* Pruned length of Subject's comparison pointer list */ 93 | 94 | 95 | 96 | /* Take Subject's points and compute pointwise comparison statistics table and sorted row-pointer list. */ 97 | /* This builds a "Web" of relative edge statistics between points. */ 98 | bz_comp( 99 | pstruct->nrows, 100 | pstruct->xcol, 101 | pstruct->ycol, 102 | pstruct->thetacol, 103 | &sim, 104 | scols, 105 | scolpt ); 106 | 107 | msim = sim; /* Init search to end of Subject's pointwise comparison table (last edge in Web) */ 108 | 109 | 110 | 111 | bz_find( &msim, scolpt ); 112 | 113 | 114 | 115 | if ( msim < FDD ) /* Makes sure there are a reasonable number of edges (at least 500, if possible) to analyze in the Web */ 116 | msim = ( sim > FDD ) ? FDD : sim; 117 | 118 | 119 | 120 | 121 | 122 | return msim; 123 | } 124 | 125 | /**************************************************************************/ 126 | 127 | int bozorth_gallery_init( struct xyt_struct * gstruct ) 128 | { 129 | int fim; /* number of pointwise comparisons for On-File record*/ 130 | int mfim; /* Pruned length of On-File Record's pointer list */ 131 | 132 | 133 | /* Take On-File Record's points and compute pointwise comparison statistics table and sorted row-pointer list. */ 134 | /* This builds a "Web" of relative edge statistics between points. */ 135 | bz_comp( 136 | gstruct->nrows, 137 | gstruct->xcol, 138 | gstruct->ycol, 139 | gstruct->thetacol, 140 | &fim, 141 | fcols, 142 | fcolpt ); 143 | 144 | mfim = fim; /* Init search to end of On-File Record's pointwise comparison table (last edge in Web) */ 145 | 146 | 147 | 148 | bz_find( &mfim, fcolpt ); 149 | 150 | 151 | 152 | if ( mfim < FDD ) /* Makes sure there are a reasonable number of edges (at least 500, if possible) to analyze in the Web */ 153 | mfim = ( fim > FDD ) ? FDD : fim; 154 | 155 | 156 | 157 | 158 | 159 | return mfim; 160 | } 161 | 162 | /**************************************************************************/ 163 | 164 | int bozorth_to_gallery( 165 | int probe_len, 166 | struct xyt_struct * pstruct, 167 | struct xyt_struct * gstruct 168 | ) 169 | { 170 | int np; 171 | int gallery_len; 172 | 173 | gallery_len = bozorth_gallery_init( gstruct ); 174 | np = bz_match( probe_len, gallery_len ); 175 | return bz_match_score( np, pstruct, gstruct ); 176 | } 177 | 178 | /**************************************************************************/ 179 | 180 | int bozorth_main( 181 | struct xyt_struct * pstruct, 182 | struct xyt_struct * gstruct 183 | ) 184 | { 185 | int ms; 186 | int np; 187 | int probe_len; 188 | int gallery_len; 189 | 190 | 191 | 192 | #ifdef DEBUG 193 | printf( "PROBE_INIT() called\n" ); 194 | #endif 195 | probe_len = bozorth_probe_init( pstruct ); 196 | 197 | 198 | #ifdef DEBUG 199 | printf( "GALLERY_INIT() called\n" ); 200 | #endif 201 | gallery_len = bozorth_gallery_init( gstruct ); 202 | 203 | 204 | #ifdef DEBUG 205 | printf( "BZ_MATCH() called\n" ); 206 | #endif 207 | np = bz_match( probe_len, gallery_len ); 208 | 209 | 210 | #ifdef DEBUG 211 | printf( "BZ_MATCH() returned %d edge pairs\n", np ); 212 | printf( "COMPUTE() called\n" ); 213 | #endif 214 | ms = bz_match_score( np, pstruct, gstruct ); 215 | 216 | 217 | #ifdef DEBUG 218 | printf( "COMPUTE() returned %d\n", ms ); 219 | #endif 220 | 221 | 222 | return ms; 223 | } 224 | -------------------------------------------------------------------------------- /libfprint/nbis/bozorth3/bz_gbls.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | 3 | This file is part of the Export Control subset of the United States NIST 4 | Biometric Image Software (NBIS) distribution: 5 | http://fingerprint.nist.gov/NBIS/index.html 6 | 7 | It is our understanding that this falls within ECCN 3D980, which covers 8 | software associated with the development, production or use of certain 9 | equipment controlled in accordance with U.S. concerns about crime control 10 | practices in specific countries. 11 | 12 | Therefore, this file should not be exported, or made available on fileservers, 13 | except as allowed by U.S. export control laws. 14 | 15 | Do not remove this notice. 16 | 17 | ******************************************************************************/ 18 | 19 | /* NOTE: Despite the above notice (which I have not removed), this file is 20 | * being legally distributed within libfprint; the U.S. Export Administration 21 | * Regulations do not place export restrictions upon distribution of 22 | * "publicly available technology and software", as stated in EAR section 23 | * 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per 24 | * the definition in section 734.7(a)(1). 25 | * 26 | * For further information, see http://reactivated.net/fprint/US_export_control 27 | */ 28 | 29 | /******************************************************************************* 30 | 31 | License: 32 | This software was developed at the National Institute of Standards and 33 | Technology (NIST) by employees of the Federal Government in the course 34 | of their official duties. Pursuant to title 17 Section 105 of the 35 | United States Code, this software is not subject to copyright protection 36 | and is in the public domain. NIST assumes no responsibility whatsoever for 37 | its use by other parties, and makes no guarantees, expressed or implied, 38 | about its quality, reliability, or any other characteristic. 39 | 40 | Disclaimer: 41 | This software was developed to promote biometric standards and biometric 42 | technology testing for the Federal Government in accordance with the USA 43 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 44 | Specific hardware and software products identified in this software were used 45 | in order to perform the software development. In no case does such 46 | identification imply recommendation or endorsement by the National Institute 47 | of Standards and Technology, nor does it imply that the products and equipment 48 | identified are necessarily the best available for the purpose. 49 | 50 | *******************************************************************************/ 51 | 52 | /*********************************************************************** 53 | LIBRARY: FING - NIST Fingerprint Systems Utilities 54 | 55 | FILE: BZ_GBLS.C 56 | ALGORITHM: Allan S. Bozorth (FBI) 57 | MODIFICATIONS: Michael D. Garris (NIST) 58 | Stan Janet (NIST) 59 | DATE: 09/21/2004 60 | 61 | Contains global variables responsible for supporting the 62 | Bozorth3 fingerprint matching "core" algorithm. 63 | 64 | *********************************************************************** 65 | ***********************************************************************/ 66 | 67 | #include 68 | 69 | /**************************************************************************/ 70 | /* General supporting global variables */ 71 | /**************************************************************************/ 72 | 73 | int colp[ COLP_SIZE_1 ][ COLP_SIZE_2 ]; /* Output from match(), this is a sorted table of compatible edge pairs containing: */ 74 | /* DeltaThetaKJs, Subject's K, J, then On-File's {K,J} or {J,K} depending */ 75 | /* Sorted first on Subject's point index K, */ 76 | /* then On-File's K or J point index (depending), */ 77 | /* lastly on Subject's J point index */ 78 | int scols[ SCOLS_SIZE_1 ][ COLS_SIZE_2 ]; /* Subject's pointwise comparison table containing: */ 79 | /* Distance,min(BetaK,BetaJ),max(BetaK,BbetaJ), K,J,ThetaKJ */ 80 | int fcols[ FCOLS_SIZE_1 ][ COLS_SIZE_2 ]; /* On-File Record's pointwise comparison table with: */ 81 | /* Distance,min(BetaK,BetaJ),max(BetaK,BbetaJ),K,J, ThetaKJ */ 82 | int * scolpt[ SCOLPT_SIZE ]; /* Subject's list of pointers to pointwise comparison rows, sorted on: */ 83 | /* Distance, min(BetaK,BetaJ), then max(BetaK,BetaJ) */ 84 | int * fcolpt[ FCOLPT_SIZE ]; /* On-File Record's list of pointers to pointwise comparison rows sorted on: */ 85 | /* Distance, min(BetaK,BetaJ), then max(BetaK,BetaJ) */ 86 | int sc[ SC_SIZE ]; /* Flags all compatible edges in the Subject's Web */ 87 | 88 | int yl[ YL_SIZE_1 ][ YL_SIZE_2 ]; 89 | 90 | 91 | /**************************************************************************/ 92 | /* Globals used significantly by sift() */ 93 | /**************************************************************************/ 94 | int rq[ RQ_SIZE ] = {}; 95 | int tq[ TQ_SIZE ] = {}; 96 | int zz[ ZZ_SIZE ] = {}; 97 | 98 | int rx[ RX_SIZE ] = {}; 99 | int mm[ MM_SIZE ] = {}; 100 | int nn[ NN_SIZE ] = {}; 101 | 102 | int qq[ QQ_SIZE ] = {}; 103 | 104 | int rk[ RK_SIZE ] = {}; 105 | 106 | int cp[ CP_SIZE ] = {}; 107 | int rp[ RP_SIZE ] = {}; 108 | 109 | int rf[RF_SIZE_1][RF_SIZE_2] = {}; 110 | int cf[CF_SIZE_1][CF_SIZE_2] = {}; 111 | 112 | int y[20000] = {}; 113 | 114 | -------------------------------------------------------------------------------- /libfprint/nbis/bozorth3/bz_sort.c: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | 3 | This file is part of the Export Control subset of the United States NIST 4 | Biometric Image Software (NBIS) distribution: 5 | http://fingerprint.nist.gov/NBIS/index.html 6 | 7 | It is our understanding that this falls within ECCN 3D980, which covers 8 | software associated with the development, production or use of certain 9 | equipment controlled in accordance with U.S. concerns about crime control 10 | practices in specific countries. 11 | 12 | Therefore, this file should not be exported, or made available on fileservers, 13 | except as allowed by U.S. export control laws. 14 | 15 | Do not remove this notice. 16 | 17 | ******************************************************************************/ 18 | 19 | /* NOTE: Despite the above notice (which I have not removed), this file is 20 | * being legally distributed within libfprint; the U.S. Export Administration 21 | * Regulations do not place export restrictions upon distribution of 22 | * "publicly available technology and software", as stated in EAR section 23 | * 734.3(b)(3)(i). libfprint qualifies as publicly available technology as per 24 | * the definition in section 734.7(a)(1). 25 | * 26 | * For further information, see http://reactivated.net/fprint/US_export_control 27 | */ 28 | 29 | /******************************************************************************* 30 | 31 | License: 32 | This software was developed at the National Institute of Standards and 33 | Technology (NIST) by employees of the Federal Government in the course 34 | of their official duties. Pursuant to title 17 Section 105 of the 35 | United States Code, this software is not subject to copyright protection 36 | and is in the public domain. NIST assumes no responsibility whatsoever for 37 | its use by other parties, and makes no guarantees, expressed or implied, 38 | about its quality, reliability, or any other characteristic. 39 | 40 | Disclaimer: 41 | This software was developed to promote biometric standards and biometric 42 | technology testing for the Federal Government in accordance with the USA 43 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 44 | Specific hardware and software products identified in this software were used 45 | in order to perform the software development. In no case does such 46 | identification imply recommendation or endorsement by the National Institute 47 | of Standards and Technology, nor does it imply that the products and equipment 48 | identified are necessarily the best available for the purpose. 49 | 50 | *******************************************************************************/ 51 | 52 | /*********************************************************************** 53 | LIBRARY: FING - NIST Fingerprint Systems Utilities 54 | 55 | FILE: BZ_SORT.C 56 | ALGORITHM: Allan S. Bozorth (FBI) 57 | MODIFICATIONS: Michael D. Garris (NIST) 58 | Stan Janet (NIST) 59 | DATE: 09/21/2004 60 | 61 | Contains sorting routines responsible for supporting the 62 | Bozorth3 fingerprint matching algorithm. 63 | 64 | *********************************************************************** 65 | 66 | ROUTINES: 67 | #cat: sort_quality_decreasing - comparison function passed to stdlib 68 | #cat: qsort() used to sort minutia qualities 69 | #cat: sort_x_y - comparison function passed to stdlib qsort() used 70 | #cat: to sort minutia coordinates increasing first on x 71 | #cat: then on y 72 | #cat: sort_order_decreasing - calls a custom quicksort that sorts 73 | #cat: a list of integers in decreasing order 74 | 75 | ***********************************************************************/ 76 | 77 | #include 78 | #include 79 | 80 | /* These are now externally defined in bozorth.h */ 81 | /* extern char * get_progname( void ); */ 82 | 83 | /***********************************************************************/ 84 | int sort_quality_decreasing( const void * a, const void * b ) 85 | { 86 | struct minutiae_struct * af; 87 | struct minutiae_struct * bf; 88 | 89 | af = (struct minutiae_struct *) a; 90 | bf = (struct minutiae_struct *) b; 91 | 92 | if ( af->col[3] > bf->col[3] ) 93 | return -1; 94 | if ( af->col[3] < bf->col[3] ) 95 | return 1; 96 | return 0; 97 | } 98 | 99 | /***********************************************************************/ 100 | int sort_x_y( const void * a, const void * b ) 101 | { 102 | struct minutiae_struct * af; 103 | struct minutiae_struct * bf; 104 | 105 | af = (struct minutiae_struct *) a; 106 | bf = (struct minutiae_struct *) b; 107 | 108 | if ( af->col[0] < bf->col[0] ) 109 | return -1; 110 | if ( af->col[0] > bf->col[0] ) 111 | return 1; 112 | 113 | if ( af->col[1] < bf->col[1] ) 114 | return -1; 115 | if ( af->col[1] > bf->col[1] ) 116 | return 1; 117 | 118 | return 0; 119 | } 120 | 121 | /******************************************************** 122 | qsort_decreasing() - quicksort an array of integers in decreasing 123 | order [based on multisort.c, by Michael Garris 124 | and Ted Zwiesler, 1986] 125 | ********************************************************/ 126 | /* Used by custom quicksort code below */ 127 | static int stack[BZ_STACKSIZE]; 128 | static int * stack_pointer = stack; 129 | 130 | /***********************************************************************/ 131 | /* return values: 0 == successful, 1 == error */ 132 | static int popstack( int *popval ) 133 | { 134 | if ( --stack_pointer < stack ) { 135 | fprintf( stderr, "%s: ERROR: popstack(): stack underflow\n", get_progname() ); 136 | return 1; 137 | } 138 | 139 | *popval = *stack_pointer; 140 | return 0; 141 | } 142 | 143 | /***********************************************************************/ 144 | /* return values: 0 == successful, 1 == error */ 145 | static int pushstack( int position ) 146 | { 147 | *stack_pointer++ = position; 148 | if ( stack_pointer > ( stack + BZ_STACKSIZE ) ) { 149 | fprintf( stderr, "%s: ERROR: pushstack(): stack overflow\n", get_progname() ); 150 | return 1; 151 | } 152 | return 0; 153 | } 154 | 155 | /***********************************************************************/ 156 | /******************************************************************* 157 | select_pivot() 158 | selects a pivot from a list being sorted using the Singleton Method. 159 | *******************************************************************/ 160 | static int select_pivot( struct cell v[], int left, int right ) 161 | { 162 | int midpoint; 163 | 164 | 165 | midpoint = ( left + right ) / 2; 166 | if ( v[left].index <= v[midpoint].index ) { 167 | if ( v[midpoint].index <= v[right].index ) { 168 | return midpoint; 169 | } else { 170 | if ( v[right].index > v[left].index ) { 171 | return right; 172 | } else { 173 | return left; 174 | } 175 | } 176 | } else { 177 | if ( v[left].index < v[right].index ) { 178 | return left; 179 | } else { 180 | if ( v[right].index < v[midpoint].index ) { 181 | return midpoint; 182 | } else { 183 | return right; 184 | } 185 | } 186 | } 187 | } 188 | 189 | /***********************************************************************/ 190 | /******************************************************** 191 | partition_dec() 192 | Inputs a pivot element making comparisons and swaps with other elements in a list, 193 | until pivot resides at its correct position in the list. 194 | ********************************************************/ 195 | static void partition_dec( struct cell v[], int *llen, int *rlen, int *ll, int *lr, int *rl, int *rr, int p, int l, int r ) 196 | { 197 | #define iswap(a,b) { int itmp = (a); a = (b); b = itmp; } 198 | 199 | *ll = l; 200 | *rr = r; 201 | while ( 1 ) { 202 | if ( l < p ) { 203 | if ( v[l].index < v[p].index ) { 204 | iswap( v[l].index, v[p].index ) 205 | iswap( v[l].item, v[p].item ) 206 | p = l; 207 | } else { 208 | l++; 209 | } 210 | } else { 211 | if ( r > p ) { 212 | if ( v[r].index > v[p].index ) { 213 | iswap( v[r].index, v[p].index ) 214 | iswap( v[r].item, v[p].item ) 215 | p = r; 216 | l++; 217 | } else { 218 | r--; 219 | } 220 | } else { 221 | *lr = p - 1; 222 | *rl = p + 1; 223 | *llen = *lr - *ll + 1; 224 | *rlen = *rr - *rl + 1; 225 | break; 226 | } 227 | } 228 | } 229 | } 230 | 231 | /***********************************************************************/ 232 | /******************************************************** 233 | qsort_decreasing() 234 | This procedure inputs a pointer to an index_struct, the subscript of an index array to be 235 | sorted, a left subscript pointing to where the sort is to begin in the index array, and a right 236 | subscript where to end. This module invokes a decreasing quick-sort sorting the index array from l to r. 237 | ********************************************************/ 238 | /* return values: 0 == successful, 1 == error */ 239 | static int qsort_decreasing( struct cell v[], int left, int right ) 240 | { 241 | int pivot; 242 | int llen, rlen; 243 | int lleft, lright, rleft, rright; 244 | 245 | 246 | if ( pushstack( left )) 247 | return 1; 248 | if ( pushstack( right )) 249 | return 2; 250 | while ( stack_pointer != stack ) { 251 | if (popstack(&right)) 252 | return 3; 253 | if (popstack(&left )) 254 | return 4; 255 | if ( right - left > 0 ) { 256 | pivot = select_pivot( v, left, right ); 257 | partition_dec( v, &llen, &rlen, &lleft, &lright, &rleft, &rright, pivot, left, right ); 258 | if ( llen > rlen ) { 259 | if ( pushstack( lleft )) 260 | return 5; 261 | if ( pushstack( lright )) 262 | return 6; 263 | if ( pushstack( rleft )) 264 | return 7; 265 | if ( pushstack( rright )) 266 | return 8; 267 | } else{ 268 | if ( pushstack( rleft )) 269 | return 9; 270 | if ( pushstack( rright )) 271 | return 10; 272 | if ( pushstack( lleft )) 273 | return 11; 274 | if ( pushstack( lright )) 275 | return 12; 276 | } 277 | } 278 | } 279 | return 0; 280 | } 281 | 282 | /***********************************************************************/ 283 | /* return values: 0 == successful, 1 == error */ 284 | int sort_order_decreasing( 285 | int values[], /* INPUT: the unsorted values themselves */ 286 | int num, /* INPUT: the number of values */ 287 | int order[] /* OUTPUT: the order for each of the values if sorted */ 288 | ) 289 | { 290 | int i; 291 | struct cell * cells; 292 | 293 | 294 | cells = (struct cell *) malloc( num * sizeof(struct cell) ); 295 | if ( cells == (struct cell *) NULL ){ 296 | fprintf( stderr, "%s: ERROR: malloc(): struct cell\n", get_progname() ); 297 | return 1; 298 | } 299 | 300 | for( i = 0; i < num; i++ ) { 301 | cells[i].index = values[i]; 302 | cells[i].item = i; 303 | } 304 | 305 | if ( qsort_decreasing( cells, 0, num-1 ) < 0) 306 | return 2; 307 | 308 | for( i = 0; i < num; i++ ) { 309 | order[i] = cells[i].item; 310 | } 311 | 312 | free( (void *) cells ); 313 | 314 | return 0; 315 | } 316 | -------------------------------------------------------------------------------- /libfprint/nbis/include/bozorth.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | 3 | License: 4 | This software was developed at the National Institute of Standards and 5 | Technology (NIST) by employees of the Federal Government in the course 6 | of their official duties. Pursuant to title 17 Section 105 of the 7 | United States Code, this software is not subject to copyright protection 8 | and is in the public domain. NIST assumes no responsibility whatsoever for 9 | its use by other parties, and makes no guarantees, expressed or implied, 10 | about its quality, reliability, or any other characteristic. 11 | 12 | Disclaimer: 13 | This software was developed to promote biometric standards and biometric 14 | technology testing for the Federal Government in accordance with the USA 15 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 16 | Specific hardware and software products identified in this software were used 17 | in order to perform the software development. In no case does such 18 | identification imply recommendation or endorsement by the National Institute 19 | of Standards and Technology, nor does it imply that the products and equipment 20 | identified are necessarily the best available for the purpose. 21 | 22 | *******************************************************************************/ 23 | 24 | #ifndef _BOZORTH_H 25 | #define _BOZORTH_H 26 | 27 | /* The max number of points in any Probe or Gallery XYT is set to 200; */ 28 | /* a pointwise comparison table therefore has a maximum number of: */ 29 | /* (200^2)/2 = 20000 comparisons. */ 30 | 31 | 32 | #include 33 | #include 34 | #include 35 | #include /* Needed for type pid_t */ 36 | #include 37 | 38 | /* If not defined in sys/param.h */ 39 | #ifndef MAX 40 | #define MAX(a,b) (((a)>(b))?(a):(b)) 41 | #endif 42 | 43 | /**************************************************************************/ 44 | /* Math-Related Macros, Definitions & Prototypes */ 45 | /**************************************************************************/ 46 | #include 47 | /* This macro adjusts angles to the range (-180,180] */ 48 | #define IANGLE180(deg) ( ( (deg) > 180 ) ? ( (deg) - 360 ) : ( (deg) <= -180 ? ( (deg) + 360 ) : (deg) ) ) 49 | 50 | #define SENSE(a,b) ( (a) < (b) ? (-1) : ( ( (a) == (b) ) ? 0 : 1 ) ) 51 | #define SENSE_NEG_POS(a,b) ( (a) < (b) ? (-1) : 1 ) 52 | 53 | #define SQUARED(n) ( (n) * (n) ) 54 | 55 | #ifdef ROUND_USING_LIBRARY 56 | /* These functions should be declared in math.h: 57 | extern float roundf( float ); 58 | extern double round( double ); 59 | */ 60 | #define ROUND(f) (roundf(f)) 61 | #else 62 | #define ROUND(f) ( ( (f) < 0.0F ) ? ( (int) ( (f) - 0.5F ) ) : ( (int) ( (f) + 0.5F ) ) ) 63 | #endif 64 | 65 | /* PI is used in: bozorth3.c, comp.c */ 66 | #ifdef M_PI 67 | #define PI M_PI 68 | #define PI_SINGLE ( (float) PI ) 69 | #else 70 | #define PI 3.14159 71 | #define PI_SINGLE 3.14159F 72 | #endif 73 | 74 | /* Provide prototype for atanf() */ 75 | extern float atanf( float ); 76 | 77 | /**************************************************************************/ 78 | /* Array Length Definitions */ 79 | /**************************************************************************/ 80 | #include 81 | 82 | 83 | /**************************************************************************/ 84 | /**************************************************************************/ 85 | /* GENERAL DEFINITIONS */ 86 | /**************************************************************************/ 87 | 88 | #define FPNULL ((FILE *) NULL) 89 | #define CNULL ((char *) NULL) 90 | 91 | #define PROGRAM "bozorth3" 92 | 93 | #define MAX_LINE_LENGTH 1024 94 | 95 | #define SCOREFILE_EXTENSION ".scr" 96 | 97 | #define MAX_FILELIST_LENGTH 10000 98 | 99 | #define DEFAULT_BOZORTH_MINUTIAE 150 100 | #define MAX_BOZORTH_MINUTIAE 200 101 | #define MIN_BOZORTH_MINUTIAE 0 102 | #define MIN_COMPUTABLE_BOZORTH_MINUTIAE 10 103 | 104 | #define DEFAULT_MAX_MATCH_SCORE 400 105 | #define ZERO_MATCH_SCORE 0 106 | 107 | #define DEFAULT_SCORE_LINE_FORMAT "s" 108 | 109 | #define DM 125 110 | #define FD 5625 111 | #define FDD 500 112 | #define TK 0.05F 113 | #define TXS 121 114 | #define CTXS 121801 115 | #define MSTR 3 116 | #define MMSTR 8 117 | #define WWIM 10 118 | 119 | #define QQ_SIZE 4000 120 | 121 | #define QQ_OVERFLOW_SCORE QQ_SIZE 122 | 123 | /**************************************************************************/ 124 | /**************************************************************************/ 125 | /* MACROS DEFINITIONS */ 126 | /**************************************************************************/ 127 | #define INT_SET(dst,count,value) { \ 128 | int * int_set_dst = (dst); \ 129 | int int_set_count = (count); \ 130 | int int_set_value = (value); \ 131 | while ( int_set_count-- > 0 ) \ 132 | *int_set_dst++ = int_set_value; \ 133 | } 134 | 135 | /* The code that calls it assumed dst gets bumped, so don't assign to a local variable */ 136 | #define INT_COPY(dst,src,count) { \ 137 | int * int_copy_src = (src); \ 138 | int int_copy_count = (count); \ 139 | while ( int_copy_count-- > 0 ) \ 140 | *dst++ = *int_copy_src++; \ 141 | } 142 | 143 | 144 | /**************************************************************************/ 145 | /**************************************************************************/ 146 | /* STRUCTURES & TYPEDEFS */ 147 | /**************************************************************************/ 148 | 149 | /**************************************************************************/ 150 | /* In BZ_SORT.C - supports stdlib qsort() and customized quicksort */ 151 | /**************************************************************************/ 152 | 153 | /* Used by call to stdlib qsort() */ 154 | struct minutiae_struct { 155 | int col[4]; 156 | }; 157 | 158 | /* Used by custom quicksort */ 159 | #define BZ_STACKSIZE 1000 160 | struct cell { 161 | int index; /* pointer to an array of pointers to index arrays */ 162 | int item; /* pointer to an item array */ 163 | }; 164 | 165 | /**************************************************************************/ 166 | /* In BZ_IO : Supports the loading and manipulation of XYT data */ 167 | /**************************************************************************/ 168 | #define MAX_FILE_MINUTIAE 1000 /* bz_load() */ 169 | 170 | struct xyt_struct { 171 | int nrows; 172 | int xcol[ MAX_BOZORTH_MINUTIAE ]; 173 | int ycol[ MAX_BOZORTH_MINUTIAE ]; 174 | int thetacol[ MAX_BOZORTH_MINUTIAE ]; 175 | }; 176 | 177 | #define XYT_NULL ( (struct xyt_struct *) NULL ) /* bz_load() */ 178 | 179 | 180 | /**************************************************************************/ 181 | /**************************************************************************/ 182 | /* GLOBAL VARIABLES */ 183 | /**************************************************************************/ 184 | 185 | /**************************************************************************/ 186 | /* In: SRC/BIN/BOZORTH3/BOZORTH3.C */ 187 | /**************************************************************************/ 188 | /* Globals supporting command line options */ 189 | extern int verbose_threshold; 190 | 191 | /**************************************************************************/ 192 | /* In: BZ_GBLS.C */ 193 | /**************************************************************************/ 194 | /* Global arrays supporting "core" bozorth algorithm */ 195 | extern int colp[ COLP_SIZE_1 ][ COLP_SIZE_2 ]; 196 | extern int scols[ SCOLS_SIZE_1 ][ COLS_SIZE_2 ]; 197 | extern int fcols[ FCOLS_SIZE_1 ][ COLS_SIZE_2 ]; 198 | extern int * scolpt[ SCOLPT_SIZE ]; 199 | extern int * fcolpt[ FCOLPT_SIZE ]; 200 | extern int sc[ SC_SIZE ]; 201 | extern int yl[ YL_SIZE_1 ][ YL_SIZE_2 ]; 202 | /* Global arrays supporting "core" bozorth algorithm continued: */ 203 | /* Globals used significantly by sift() */ 204 | extern int rq[ RQ_SIZE ]; 205 | extern int tq[ TQ_SIZE ]; 206 | extern int zz[ ZZ_SIZE ]; 207 | extern int rx[ RX_SIZE ]; 208 | extern int mm[ MM_SIZE ]; 209 | extern int nn[ NN_SIZE ]; 210 | extern int qq[ QQ_SIZE ]; 211 | extern int rk[ RK_SIZE ]; 212 | extern int cp[ CP_SIZE ]; 213 | extern int rp[ RP_SIZE ]; 214 | extern int rf[RF_SIZE_1][RF_SIZE_2]; 215 | extern int cf[CF_SIZE_1][CF_SIZE_2]; 216 | extern int y[20000]; 217 | 218 | /**************************************************************************/ 219 | /**************************************************************************/ 220 | /* ROUTINE PROTOTYPES */ 221 | /**************************************************************************/ 222 | /* In: BZ_DRVRS.C */ 223 | extern int bozorth_probe_init( struct xyt_struct *); 224 | extern int bozorth_gallery_init( struct xyt_struct *); 225 | extern int bozorth_to_gallery(int, struct xyt_struct *, struct xyt_struct *); 226 | extern int bozorth_main(struct xyt_struct *, struct xyt_struct *); 227 | /* In: BOZORTH3.C */ 228 | extern void bz_comp(int, int [], int [], int [], int *, int [][COLS_SIZE_2], 229 | int *[]); 230 | extern void bz_find(int *, int *[]); 231 | extern int bz_match(int, int); 232 | extern int bz_match_score(int, struct xyt_struct *, struct xyt_struct *); 233 | extern void bz_sift(int *, int, int *, int, int, int, int *, int *); 234 | /* In: BZ_ALLOC.C */ 235 | extern char *malloc_or_exit(int, const char *); 236 | extern char *malloc_or_return_error(int, const char *); 237 | /* In: BZ_IO.C */ 238 | extern int parse_line_range(const char *, int *, int *); 239 | extern void set_progname(int, char *, pid_t); 240 | extern void set_probe_filename(char *); 241 | extern void set_gallery_filename(char *); 242 | extern char *get_progname(void); 243 | extern char *get_probe_filename(void); 244 | extern char *get_gallery_filename(void); 245 | extern char *get_next_file(char *, FILE *, FILE *, int *, int *, char *, 246 | int, char **, int *, int *, int, int); 247 | extern char *get_score_filename(const char *, const char *); 248 | extern char *get_score_line(const char *, const char *, int, int, const char *); 249 | extern struct xyt_struct *bz_load(const char *); 250 | extern int fd_readable(int); 251 | /* In: BZ_SORT.C */ 252 | extern int sort_quality_decreasing(const void *, const void *); 253 | extern int sort_x_y(const void *, const void *); 254 | extern int sort_order_decreasing(int [], int, int []); 255 | 256 | #endif /* !_BOZORTH_H */ 257 | -------------------------------------------------------------------------------- /libfprint/nbis/include/bz_array.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | 3 | License: 4 | This software was developed at the National Institute of Standards and 5 | Technology (NIST) by employees of the Federal Government in the course 6 | of their official duties. Pursuant to title 17 Section 105 of the 7 | United States Code, this software is not subject to copyright protection 8 | and is in the public domain. NIST assumes no responsibility whatsoever for 9 | its use by other parties, and makes no guarantees, expressed or implied, 10 | about its quality, reliability, or any other characteristic. 11 | 12 | Disclaimer: 13 | This software was developed to promote biometric standards and biometric 14 | technology testing for the Federal Government in accordance with the USA 15 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 16 | Specific hardware and software products identified in this software were used 17 | in order to perform the software development. In no case does such 18 | identification imply recommendation or endorsement by the National Institute 19 | of Standards and Technology, nor does it imply that the products and equipment 20 | identified are necessarily the best available for the purpose. 21 | 22 | *******************************************************************************/ 23 | 24 | #ifndef _BZ_ARRAY_H 25 | #define _BZ_ARRAY_H 26 | 27 | #define STATIC static 28 | /* #define BAD_BOUNDS 1 */ 29 | 30 | #define COLP_SIZE_1 20000 31 | #define COLP_SIZE_2 5 32 | 33 | #define COLS_SIZE_2 6 34 | #define SCOLS_SIZE_1 20000 35 | #define FCOLS_SIZE_1 20000 36 | 37 | #define SCOLPT_SIZE 20000 38 | #define FCOLPT_SIZE 20000 39 | 40 | #define SC_SIZE 20000 41 | 42 | 43 | #define RQ_SIZE 20000 44 | #define TQ_SIZE 20000 45 | #define ZZ_SIZE 20000 46 | 47 | 48 | 49 | #define RX_SIZE 100 50 | #define MM_SIZE 100 51 | #define NN_SIZE 20 52 | 53 | 54 | 55 | #define RK_SIZE 20000 56 | 57 | 58 | 59 | #define RR_SIZE 100 60 | #define AVN_SIZE 5 61 | #define AVV_SIZE_1 2000 62 | #define AVV_SIZE_2 5 63 | #define CT_SIZE 2000 64 | #define GCT_SIZE 2000 65 | #define CTT_SIZE 2000 66 | 67 | 68 | #ifdef BAD_BOUNDS 69 | #define CTP_SIZE_1 2000 70 | #define CTP_SIZE_2 1000 71 | #else 72 | #define CTP_SIZE_1 2000 73 | #define CTP_SIZE_2 2500 74 | #endif 75 | 76 | 77 | 78 | /* 79 | rp[x] == ctp[][x] :: sct[x][] 80 | */ 81 | 82 | 83 | 84 | 85 | #define RF_SIZE_1 100 86 | #define RF_SIZE_2 10 87 | 88 | #define CF_SIZE_1 100 89 | #define CF_SIZE_2 10 90 | 91 | #define Y_SIZE 20000 92 | 93 | 94 | 95 | 96 | 97 | 98 | #define YL_SIZE_1 2 99 | #define YL_SIZE_2 2000 100 | 101 | 102 | 103 | 104 | #define YY_SIZE_1 1000 105 | #define YY_SIZE_2 2 106 | #define YY_SIZE_3 2000 107 | 108 | 109 | 110 | #ifdef BAD_BOUNDS 111 | #define SCT_SIZE_1 1000 112 | #define SCT_SIZE_2 1000 113 | #else 114 | #define SCT_SIZE_1 2500 115 | #define SCT_SIZE_2 1000 116 | #endif 117 | 118 | #define CP_SIZE 20000 119 | #define RP_SIZE 20000 120 | 121 | #endif /* !_BZ_ARRAY_H */ 122 | -------------------------------------------------------------------------------- /libfprint/nbis/include/defs.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | 3 | License: 4 | This software was developed at the National Institute of Standards and 5 | Technology (NIST) by employees of the Federal Government in the course 6 | of their official duties. Pursuant to title 17 Section 105 of the 7 | United States Code, this software is not subject to copyright protection 8 | and is in the public domain. NIST assumes no responsibility whatsoever for 9 | its use by other parties, and makes no guarantees, expressed or implied, 10 | about its quality, reliability, or any other characteristic. 11 | 12 | Disclaimer: 13 | This software was developed to promote biometric standards and biometric 14 | technology testing for the Federal Government in accordance with the USA 15 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 16 | Specific hardware and software products identified in this software were used 17 | in order to perform the software development. In no case does such 18 | identification imply recommendation or endorsement by the National Institute 19 | of Standards and Technology, nor does it imply that the products and equipment 20 | identified are necessarily the best available for the purpose. 21 | 22 | *******************************************************************************/ 23 | 24 | #ifndef _DEFS_H 25 | #define _DEFS_H 26 | 27 | /*********************************************************************/ 28 | /* General Purpose Defines */ 29 | /*********************************************************************/ 30 | #ifndef True 31 | #define True 1 32 | #define False 0 33 | #endif 34 | #ifndef TRUE 35 | #define TRUE True 36 | #define FALSE False 37 | #endif 38 | #define Yes True 39 | #define No False 40 | #define Empty NULL 41 | #ifndef None 42 | #define None -1 43 | #endif 44 | #ifndef FOUND 45 | #define FOUND 1 46 | #endif 47 | #define NOT_FOUND_NEG -1 48 | #define EOL EOF 49 | #ifndef DEG2RAD 50 | #define DEG2RAD (double)(57.29578) 51 | #endif 52 | #define max(a, b) ((a) > (b) ? (a) : (b)) 53 | #define min(a, b) ((a) < (b) ? (a) : (b)) 54 | #define sround(x) ((int) (((x)<0) ? (x)-0.5 : (x)+0.5)) 55 | #define sround_uint(x) ((unsigned int) (((x)<0) ? (x)-0.5 : (x)+0.5)) 56 | #define xor(a, b) (!(a && b) && (a || b)) 57 | #define align_to_16(_v_) ((((_v_)+15)>>4)<<4) 58 | #define align_to_32(_v_) ((((_v_)+31)>>5)<<5) 59 | #ifndef CHUNKS 60 | #define CHUNKS 100 61 | #endif 62 | 63 | #endif /* !_DEFS_H */ 64 | -------------------------------------------------------------------------------- /libfprint/nbis/include/log.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | 3 | License: 4 | This software was developed at the National Institute of Standards and 5 | Technology (NIST) by employees of the Federal Government in the course 6 | of their official duties. Pursuant to title 17 Section 105 of the 7 | United States Code, this software is not subject to copyright protection 8 | and is in the public domain. NIST assumes no responsibility whatsoever for 9 | its use by other parties, and makes no guarantees, expressed or implied, 10 | about its quality, reliability, or any other characteristic. 11 | 12 | Disclaimer: 13 | This software was developed to promote biometric standards and biometric 14 | technology testing for the Federal Government in accordance with the USA 15 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 16 | Specific hardware and software products identified in this software were used 17 | in order to perform the software development. In no case does such 18 | identification imply recommendation or endorsement by the National Institute 19 | of Standards and Technology, nor does it imply that the products and equipment 20 | identified are necessarily the best available for the purpose. 21 | 22 | *******************************************************************************/ 23 | 24 | #ifndef _LOG_H 25 | #define _LOG_H 26 | 27 | /* Definitions and references to support log report files. */ 28 | /* UPDATED: 03/16/2005 by MDG */ 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #ifdef LOG_REPORT 35 | /* Uncomment the following line to enable logging. */ 36 | #define LOG_FILE "log.txt" 37 | #endif 38 | 39 | extern FILE *logfp; 40 | extern int avrdir; 41 | extern float dir_strength; 42 | extern int nvalid; 43 | 44 | extern int open_logfile(void); 45 | extern int close_logfile(void); 46 | extern void print2log(char *, ...); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /libfprint/nbis/include/morph.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | 3 | License: 4 | This software was developed at the National Institute of Standards and 5 | Technology (NIST) by employees of the Federal Government in the course 6 | of their official duties. Pursuant to title 17 Section 105 of the 7 | United States Code, this software is not subject to copyright protection 8 | and is in the public domain. NIST assumes no responsibility whatsoever for 9 | its use by other parties, and makes no guarantees, expressed or implied, 10 | about its quality, reliability, or any other characteristic. 11 | 12 | Disclaimer: 13 | This software was developed to promote biometric standards and biometric 14 | technology testing for the Federal Government in accordance with the USA 15 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 16 | Specific hardware and software products identified in this software were used 17 | in order to perform the software development. In no case does such 18 | identification imply recommendation or endorsement by the National Institute 19 | of Standards and Technology, nor does it imply that the products and equipment 20 | identified are necessarily the best available for the purpose. 21 | 22 | *******************************************************************************/ 23 | 24 | #ifndef __MORPH_H__ 25 | #define __MORPH_H__ 26 | 27 | /* Modified 10/26/1999 by MDG to avoid indisciminate erosion of pixels */ 28 | /* along the edge of the binary image. */ 29 | 30 | extern void erode_charimage_2(unsigned char *, unsigned char *, 31 | const int, const int); 32 | extern void dilate_charimage_2(unsigned char *, unsigned char *, 33 | const int, const int); 34 | extern char get_south8_2(char *, const int, const int, const int, const int); 35 | extern char get_north8_2(char *, const int, const int, const int); 36 | extern char get_east8_2(char *, const int, const int, const int); 37 | extern char get_west8_2(char *, const int, const int); 38 | 39 | #endif /* !__MORPH_H__ */ 40 | -------------------------------------------------------------------------------- /libfprint/nbis/include/sunrast.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | 3 | License: 4 | This software was developed at the National Institute of Standards and 5 | Technology (NIST) by employees of the Federal Government in the course 6 | of their official duties. Pursuant to title 17 Section 105 of the 7 | United States Code, this software is not subject to copyright protection 8 | and is in the public domain. NIST assumes no responsibility whatsoever for 9 | its use by other parties, and makes no guarantees, expressed or implied, 10 | about its quality, reliability, or any other characteristic. 11 | 12 | Disclaimer: 13 | This software was developed to promote biometric standards and biometric 14 | technology testing for the Federal Government in accordance with the USA 15 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 16 | Specific hardware and software products identified in this software were used 17 | in order to perform the software development. In no case does such 18 | identification imply recommendation or endorsement by the National Institute 19 | of Standards and Technology, nor does it imply that the products and equipment 20 | identified are necessarily the best available for the purpose. 21 | 22 | *******************************************************************************/ 23 | 24 | #ifndef _SUNRAST_H 25 | #define _SUNRAST_H 26 | 27 | /************************************************************/ 28 | /* File Name: Sunrast.h */ 29 | /* Package: Sun Rasterfile I/O */ 30 | /* Author: Michael D. Garris */ 31 | /* Date: 8/19/99 */ 32 | /* Updated: 03/16/2005 by MDG */ 33 | /* */ 34 | /************************************************************/ 35 | 36 | /* Contains header information related to Sun Rasterfile images. */ 37 | 38 | typedef struct sunrasterhdr { 39 | int magic; /* magic number */ 40 | int width; /* width (in pixels) of image */ 41 | int height; /* height (in pixels) of image */ 42 | int depth; /* depth (1, 8, or 24 bits) of pixel */ 43 | int raslength; /* length (in bytes) of image */ 44 | int rastype; /* type of file; see SUN_* below */ 45 | int maptype; /* type of colormap; see MAP_* below */ 46 | int maplength; /* length (bytes) of following map */ 47 | /* color map follows for maplength bytes, followed by image */ 48 | } SUNHEAD; 49 | 50 | #define SUN_MAGIC 0x59a66a95 51 | 52 | /* Sun supported ras_type's */ 53 | #define SUN_STANDARD 1 /* Raw pixrect image in 68000 byte order */ 54 | #define SUN_RUN_LENGTH 2 /* Run-length compression of bytes */ 55 | #define SUN_FORMAT_RGB 3 /* XRGB or RGB instead of XBGR or BGR */ 56 | #define SUN_FORMAT_TIFF 4 /* tiff <-> standard rasterfile */ 57 | #define SUN_FORMAT_IFF 5 /* iff (TAAC format) <-> standard rasterfile */ 58 | 59 | /* Sun supported maptype's */ 60 | #define MAP_RAW 2 61 | #define MAP_NONE 0 /* maplength is expected to be 0 */ 62 | #define MAP_EQUAL_RGB 1 /* red[maplength/3],green[],blue[] */ 63 | 64 | /* 65 | * NOTES: 66 | * Each line of a bitmap image should be rounded out to a multiple 67 | * of 16 bits. 68 | */ 69 | 70 | /* sunrast.c */ 71 | extern int ReadSunRaster(const char *, SUNHEAD **, unsigned char **, int *, 72 | unsigned char **, int *, int *, int *, int *); 73 | extern int WriteSunRaster(char *, unsigned char *, const int, const int, 74 | const int); 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /libfprint/nbis/mindtct/binar.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | 3 | License: 4 | This software was developed at the National Institute of Standards and 5 | Technology (NIST) by employees of the Federal Government in the course 6 | of their official duties. Pursuant to title 17 Section 105 of the 7 | United States Code, this software is not subject to copyright protection 8 | and is in the public domain. NIST assumes no responsibility whatsoever for 9 | its use by other parties, and makes no guarantees, expressed or implied, 10 | about its quality, reliability, or any other characteristic. 11 | 12 | Disclaimer: 13 | This software was developed to promote biometric standards and biometric 14 | technology testing for the Federal Government in accordance with the USA 15 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 16 | Specific hardware and software products identified in this software were used 17 | in order to perform the software development. In no case does such 18 | identification imply recommendation or endorsement by the National Institute 19 | of Standards and Technology, nor does it imply that the products and equipment 20 | identified are necessarily the best available for the purpose. 21 | 22 | *******************************************************************************/ 23 | 24 | /*********************************************************************** 25 | LIBRARY: LFS - NIST Latent Fingerprint System 26 | 27 | FILE: BINAR.C 28 | AUTHOR: Michael D. Garris 29 | DATE: 03/16/1999 30 | UPDATED: 10/04/1999 Version 2 by MDG 31 | UPDATED: 03/16/2005 by MDG 32 | 33 | Contains routines responsible for binarizing a grayscale image based 34 | on an arbitrarily-sized image and its precomputed direcitonal ridge 35 | flow (IMAP) as part of the NIST Latent Fingerprint System (LFS). 36 | 37 | *********************************************************************** 38 | ROUTINES: 39 | binarize_V2() 40 | binarize_image_V2() 41 | dirbinarize() 42 | 43 | ***********************************************************************/ 44 | 45 | #include 46 | #include 47 | #include 48 | 49 | /************************************************************************* 50 | ************************************************************************** 51 | #cat: binarize_V2 - Takes a padded grayscale input image and its associated 52 | #cat: Direction Map and produces a binarized version of the 53 | #cat: image. It then fills horizontal and vertical "holes" in 54 | #cat: the binary image results. Note that the input image must 55 | #cat: be padded sufficiently to contain in memory rotated 56 | #cat: directional binarization grids applied to pixels along the 57 | #cat: perimeter of the input image. 58 | 59 | Input: 60 | pdata - padded input grayscale image 61 | pw - padded width (in pixels) of input image 62 | ph - padded height (in pixels) of input image 63 | direction_map - 2-D vector of discrete ridge flow directions 64 | mw - width (in blocks) of the map 65 | mh - height (in blocks) of the map 66 | dirbingrids - set of rotated grid offsets used for directional 67 | binarization 68 | lfsparms - parameters and thresholds for controlling LFS 69 | Output: 70 | odata - points to created (unpadded) binary image 71 | ow - width of binary image 72 | oh - height of binary image 73 | Return Code: 74 | Zero - successful completion 75 | Negative - system error 76 | **************************************************************************/ 77 | int binarize_V2(unsigned char **odata, int *ow, int *oh, 78 | unsigned char *pdata, const int pw, const int ph, 79 | int *direction_map, const int mw, const int mh, 80 | const ROTGRIDS *dirbingrids, const LFSPARMS *lfsparms) 81 | { 82 | unsigned char *bdata; 83 | int i, bw, bh, ret; /* return code */ 84 | 85 | /* 1. Binarize the padded input image using directional block info. */ 86 | if((ret = binarize_image_V2(&bdata, &bw, &bh, pdata, pw, ph, 87 | direction_map, mw, mh, 88 | lfsparms->blocksize, dirbingrids))){ 89 | return(ret); 90 | } 91 | 92 | /* 2. Fill black and white holes in binary image. */ 93 | /* LFS scans the binary image, filling holes, 3 times. */ 94 | for(i = 0; i < lfsparms->num_fill_holes; i++) 95 | fill_holes(bdata, bw, bh); 96 | 97 | /* Return binarized input image. */ 98 | *odata = bdata; 99 | *ow = bw; 100 | *oh = bh; 101 | return(0); 102 | } 103 | 104 | /************************************************************************* 105 | ************************************************************************** 106 | #cat: binarize_image_V2 - Takes a grayscale input image and its associated 107 | #cat: Direction Map and generates a binarized version of the 108 | #cat: image. Note that there is no "Isotropic" binarization 109 | #cat: used in this version. 110 | 111 | Input: 112 | pdata - padded input grayscale image 113 | pw - padded width (in pixels) of input image 114 | ph - padded height (in pixels) of input image 115 | direction_map - 2-D vector of discrete ridge flow directions 116 | mw - width (in blocks) of the map 117 | mh - height (in blocks) of the map 118 | blocksize - dimension (in pixels) of each NMAP block 119 | dirbingrids - set of rotated grid offsets used for directional 120 | binarization 121 | Output: 122 | odata - points to binary image results 123 | ow - points to binary image width 124 | oh - points to binary image height 125 | Return Code: 126 | Zero - successful completion 127 | Negative - system error 128 | **************************************************************************/ 129 | int binarize_image_V2(unsigned char **odata, int *ow, int *oh, 130 | unsigned char *pdata, const int pw, const int ph, 131 | const int *direction_map, const int mw, const int mh, 132 | const int blocksize, const ROTGRIDS *dirbingrids) 133 | { 134 | int ix, iy, bw, bh, bx, by, mapval; 135 | unsigned char *bdata, *bptr; 136 | unsigned char *pptr, *spptr; 137 | 138 | /* Compute dimensions of "unpadded" binary image results. */ 139 | bw = pw - (dirbingrids->pad<<1); 140 | bh = ph - (dirbingrids->pad<<1); 141 | 142 | bdata = (unsigned char *)malloc(bw*bh*sizeof(unsigned char)); 143 | if(bdata == (unsigned char *)NULL){ 144 | fprintf(stderr, "ERROR : binarize_image_V2 : malloc : bdata\n"); 145 | return(-600); 146 | } 147 | 148 | bptr = bdata; 149 | spptr = pdata + (dirbingrids->pad * pw) + dirbingrids->pad; 150 | for(iy = 0; iy < bh; iy++){ 151 | /* Set pixel pointer to start of next row in grid. */ 152 | pptr = spptr; 153 | for(ix = 0; ix < bw; ix++){ 154 | 155 | /* Compute which block the current pixel is in. */ 156 | bx = (int)(ix/blocksize); 157 | by = (int)(iy/blocksize); 158 | /* Get corresponding value in Direction Map. */ 159 | mapval = *(direction_map + (by*mw) + bx); 160 | /* If current block has has INVALID direction ... */ 161 | if(mapval == INVALID_DIR) 162 | /* Set binary pixel to white (255). */ 163 | *bptr = WHITE_PIXEL; 164 | /* Otherwise, if block has a valid direction ... */ 165 | else /*if(mapval >= 0)*/ 166 | /* Use directional binarization based on block's direction. */ 167 | *bptr = dirbinarize(pptr, mapval, dirbingrids); 168 | 169 | /* Bump input and output pixel pointers. */ 170 | pptr++; 171 | bptr++; 172 | } 173 | /* Bump pointer to the next row in padded input image. */ 174 | spptr += pw; 175 | } 176 | 177 | *odata = bdata; 178 | *ow = bw; 179 | *oh = bh; 180 | return(0); 181 | } 182 | 183 | /************************************************************************* 184 | ************************************************************************** 185 | #cat: dirbinarize - Determines the binary value of a grayscale pixel based 186 | #cat: on a VALID IMAP ridge flow direction. 187 | 188 | CAUTION: The image to which the input pixel points must be appropriately 189 | padded to account for the radius of the rotated grid. Otherwise, 190 | this routine may access "unkown" memory. 191 | 192 | Input: 193 | pptr - pointer to current grayscale pixel 194 | idir - IMAP integer direction associated with the block the 195 | current is in 196 | dirbingrids - set of precomputed rotated grid offsets 197 | Return Code: 198 | BLACK_PIXEL - pixel intensity for BLACK 199 | WHITE_PIXEL - pixel intensity of WHITE 200 | **************************************************************************/ 201 | int dirbinarize(const unsigned char *pptr, const int idir, 202 | const ROTGRIDS *dirbingrids) 203 | { 204 | int gx, gy, gi, cy; 205 | int rsum, gsum, csum = 0; 206 | int *grid; 207 | double dcy; 208 | 209 | /* Assign nickname pointer. */ 210 | grid = dirbingrids->grids[idir]; 211 | /* Calculate center (0-oriented) row in grid. */ 212 | dcy = (dirbingrids->grid_h-1)/(double)2.0; 213 | /* Need to truncate precision so that answers are consistent */ 214 | /* on different computer architectures when rounding doubles. */ 215 | dcy = trunc_dbl_precision(dcy, TRUNC_SCALE); 216 | cy = sround(dcy); 217 | /* Initialize grid's pixel offset index to zero. */ 218 | gi = 0; 219 | /* Initialize grid's pixel accumulator to zero */ 220 | gsum = 0; 221 | 222 | /* Foreach row in grid ... */ 223 | for(gy = 0; gy < dirbingrids->grid_h; gy++){ 224 | /* Initialize row pixel sum to zero. */ 225 | rsum = 0; 226 | /* Foreach column in grid ... */ 227 | for(gx = 0; gx < dirbingrids->grid_w; gx++){ 228 | /* Accumulate next pixel along rotated row in grid. */ 229 | rsum += *(pptr+grid[gi]); 230 | /* Bump grid's pixel offset index. */ 231 | gi++; 232 | } 233 | /* Accumulate row sum into grid pixel sum. */ 234 | gsum += rsum; 235 | /* If current row is center row, then save row sum separately. */ 236 | if(gy == cy) 237 | csum = rsum; 238 | } 239 | 240 | /* If the center row sum treated as an average is less than the */ 241 | /* total pixel sum in the rotated grid ... */ 242 | if((csum * dirbingrids->grid_h) < gsum) 243 | /* Set the binary pixel to BLACK. */ 244 | return(BLACK_PIXEL); 245 | else 246 | /* Otherwise set the binary pixel to WHITE. */ 247 | return(WHITE_PIXEL); 248 | } 249 | 250 | -------------------------------------------------------------------------------- /libfprint/nbis/mindtct/free.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | 3 | License: 4 | This software was developed at the National Institute of Standards and 5 | Technology (NIST) by employees of the Federal Government in the course 6 | of their official duties. Pursuant to title 17 Section 105 of the 7 | United States Code, this software is not subject to copyright protection 8 | and is in the public domain. NIST assumes no responsibility whatsoever for 9 | its use by other parties, and makes no guarantees, expressed or implied, 10 | about its quality, reliability, or any other characteristic. 11 | 12 | Disclaimer: 13 | This software was developed to promote biometric standards and biometric 14 | technology testing for the Federal Government in accordance with the USA 15 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 16 | Specific hardware and software products identified in this software were used 17 | in order to perform the software development. In no case does such 18 | identification imply recommendation or endorsement by the National Institute 19 | of Standards and Technology, nor does it imply that the products and equipment 20 | identified are necessarily the best available for the purpose. 21 | 22 | *******************************************************************************/ 23 | 24 | /*********************************************************************** 25 | LIBRARY: LFS - NIST Latent Fingerprint System 26 | 27 | FILE: FREE.C 28 | AUTHOR: Michael D. Garris 29 | DATE: 03/16/1999 30 | 31 | Contains routines responsible for deallocating 32 | memories required by the NIST Latent Fingerprint System (LFS). 33 | 34 | *********************************************************************** 35 | ROUTINES: 36 | free_dir2rad() 37 | free_dftwaves() 38 | free_rotgrids() 39 | free_dir_powers() 40 | ***********************************************************************/ 41 | 42 | #include 43 | #include 44 | #include 45 | 46 | /************************************************************************* 47 | ************************************************************************** 48 | #cat: free_dir2rad - Deallocates memory associated with a DIR2RAD structure 49 | 50 | Input: 51 | dir2rad - pointer to memory to be freed 52 | *************************************************************************/ 53 | void free_dir2rad(DIR2RAD *dir2rad) 54 | { 55 | free(dir2rad->cos); 56 | free(dir2rad->sin); 57 | free(dir2rad); 58 | } 59 | 60 | /************************************************************************* 61 | ************************************************************************** 62 | #cat: free_dftwaves - Deallocates the memory associated with a DFTWAVES 63 | #cat: structure 64 | 65 | Input: 66 | dftwaves - pointer to memory to be freed 67 | **************************************************************************/ 68 | void free_dftwaves(DFTWAVES *dftwaves) 69 | { 70 | int i; 71 | 72 | for(i = 0; i < dftwaves->nwaves; i++){ 73 | free(dftwaves->waves[i]->cos); 74 | free(dftwaves->waves[i]->sin); 75 | free(dftwaves->waves[i]); 76 | } 77 | free(dftwaves->waves); 78 | free(dftwaves); 79 | } 80 | 81 | /************************************************************************* 82 | ************************************************************************** 83 | #cat: free_rotgrids - Deallocates the memory associated with a ROTGRIDS 84 | #cat: structure 85 | 86 | Input: 87 | rotgrids - pointer to memory to be freed 88 | **************************************************************************/ 89 | void free_rotgrids(ROTGRIDS *rotgrids) 90 | { 91 | int i; 92 | 93 | for(i = 0; i < rotgrids->ngrids; i++) 94 | free(rotgrids->grids[i]); 95 | free(rotgrids->grids); 96 | free(rotgrids); 97 | } 98 | 99 | /************************************************************************* 100 | ************************************************************************** 101 | #cat: free_dir_powers - Deallocate memory associated with DFT power vectors 102 | 103 | Input: 104 | powers - vectors of DFT power values (N Waves X M Directions) 105 | nwaves - number of DFT wave forms used 106 | **************************************************************************/ 107 | void free_dir_powers(double **powers, const int nwaves) 108 | { 109 | int w; 110 | 111 | for(w = 0; w < nwaves; w++) 112 | free(powers[w]); 113 | 114 | free(powers); 115 | } 116 | 117 | -------------------------------------------------------------------------------- /libfprint/nbis/mindtct/globals.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | 3 | License: 4 | This software was developed at the National Institute of Standards and 5 | Technology (NIST) by employees of the Federal Government in the course 6 | of their official duties. Pursuant to title 17 Section 105 of the 7 | United States Code, this software is not subject to copyright protection 8 | and is in the public domain. NIST assumes no responsibility whatsoever for 9 | its use by other parties, and makes no guarantees, expressed or implied, 10 | about its quality, reliability, or any other characteristic. 11 | 12 | Disclaimer: 13 | This software was developed to promote biometric standards and biometric 14 | technology testing for the Federal Government in accordance with the USA 15 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 16 | Specific hardware and software products identified in this software were used 17 | in order to perform the software development. In no case does such 18 | identification imply recommendation or endorsement by the National Institute 19 | of Standards and Technology, nor does it imply that the products and equipment 20 | identified are necessarily the best available for the purpose. 21 | 22 | *******************************************************************************/ 23 | 24 | /*********************************************************************** 25 | LIBRARY: LFS - NIST Latent Fingerprint System 26 | 27 | FILE: GLOBALS.C 28 | AUTHOR: Michael D. Garris 29 | DATE: 03/16/1999 30 | UPDATED: 10/04/1999 Version 2 by MDG 31 | 32 | Contains general global variable definitions required by the 33 | NIST Latent Fingerprint System (LFS). 34 | ***********************************************************************/ 35 | 36 | #include 37 | 38 | /*************************************************************************/ 39 | /* GOBAL DECLARATIONS */ 40 | /*************************************************************************/ 41 | 42 | #ifdef LOG_REPORT 43 | FILE *logfp; 44 | #endif 45 | 46 | /* Constants (C) for defining 4 DFT frequencies, where */ 47 | /* frequency is defined as C*(PI_FACTOR). PI_FACTOR */ 48 | /* regulates the period of the function in x, so: */ 49 | /* 1 = one period in range X. */ 50 | /* 2 = twice the frequency in range X. */ 51 | /* 3 = three times the frequency in reange X. */ 52 | /* 4 = four times the frequency in ranage X. */ 53 | double dft_coefs[NUM_DFT_WAVES] = { 1,2,3,4 }; 54 | 55 | /* Allocate and initialize a global LFS parameters structure. */ 56 | LFSPARMS lfsparms = { 57 | /* Image Controls */ 58 | PAD_VALUE, 59 | JOIN_LINE_RADIUS, 60 | 61 | /* Map Controls */ 62 | IMAP_BLOCKSIZE, 63 | UNUSED_INT, /* windowsize */ 64 | UNUSED_INT, /* windowoffset */ 65 | NUM_DIRECTIONS, 66 | START_DIR_ANGLE, 67 | RMV_VALID_NBR_MIN, 68 | DIR_STRENGTH_MIN, 69 | DIR_DISTANCE_MAX, 70 | SMTH_VALID_NBR_MIN, 71 | VORT_VALID_NBR_MIN, 72 | HIGHCURV_VORTICITY_MIN, 73 | HIGHCURV_CURVATURE_MIN, 74 | UNUSED_INT, /* min_interpolate_nbrs */ 75 | UNUSED_INT, /* percentile_min_max */ 76 | UNUSED_INT, /* min_contrast_delta */ 77 | 78 | /* DFT Controls */ 79 | NUM_DFT_WAVES, 80 | POWMAX_MIN, 81 | POWNORM_MIN, 82 | POWMAX_MAX, 83 | FORK_INTERVAL, 84 | FORK_PCT_POWMAX, 85 | FORK_PCT_POWNORM, 86 | 87 | /* Binarization Controls */ 88 | DIRBIN_GRID_W, 89 | DIRBIN_GRID_H, 90 | ISOBIN_GRID_DIM, 91 | NUM_FILL_HOLES, 92 | 93 | /* Minutiae Detection Controls */ 94 | MAX_MINUTIA_DELTA, 95 | MAX_HIGH_CURVE_THETA, 96 | HIGH_CURVE_HALF_CONTOUR, 97 | MIN_LOOP_LEN, 98 | MIN_LOOP_ASPECT_DIST, 99 | MIN_LOOP_ASPECT_RATIO, 100 | 101 | /* Minutiae Link Controls */ 102 | LINK_TABLE_DIM, 103 | MAX_LINK_DIST, 104 | MIN_THETA_DIST, 105 | MAXTRANS, 106 | SCORE_THETA_NORM, 107 | SCORE_DIST_NORM, 108 | SCORE_DIST_WEIGHT, 109 | SCORE_NUMERATOR, 110 | 111 | /* False Minutiae Removal Controls */ 112 | MAX_RMTEST_DIST, 113 | MAX_HOOK_LEN, 114 | MAX_HALF_LOOP, 115 | TRANS_DIR_PIX, 116 | SMALL_LOOP_LEN, 117 | SIDE_HALF_CONTOUR, 118 | INV_BLOCK_MARGIN, 119 | RM_VALID_NBR_MIN, 120 | UNUSED_INT, /* max_overlap_dist */ 121 | UNUSED_INT, /* max_overlap_join_dist */ 122 | UNUSED_INT, /* malformation_steps_1 */ 123 | UNUSED_INT, /* malformation_steps_2 */ 124 | UNUSED_DBL, /* min_malformation_ratio */ 125 | UNUSED_INT, /* max_malformation_dist */ 126 | PORES_TRANS_R, 127 | PORES_PERP_STEPS, 128 | PORES_STEPS_FWD, 129 | PORES_STEPS_BWD, 130 | PORES_MIN_DIST2, 131 | PORES_MAX_RATIO, 132 | 133 | /* Ridge Counting Controls */ 134 | MAX_NBRS, 135 | MAX_RIDGE_STEPS 136 | }; 137 | 138 | 139 | /* Allocate and initialize VERSION 2 global LFS parameters structure. */ 140 | LFSPARMS lfsparms_V2 = { 141 | /* Image Controls */ 142 | PAD_VALUE, 143 | JOIN_LINE_RADIUS, 144 | 145 | /* Map Controls */ 146 | MAP_BLOCKSIZE_V2, 147 | MAP_WINDOWSIZE_V2, 148 | MAP_WINDOWOFFSET_V2, 149 | NUM_DIRECTIONS, 150 | START_DIR_ANGLE, 151 | RMV_VALID_NBR_MIN, 152 | DIR_STRENGTH_MIN, 153 | DIR_DISTANCE_MAX, 154 | SMTH_VALID_NBR_MIN, 155 | VORT_VALID_NBR_MIN, 156 | HIGHCURV_VORTICITY_MIN, 157 | HIGHCURV_CURVATURE_MIN, 158 | MIN_INTERPOLATE_NBRS, 159 | PERCENTILE_MIN_MAX, 160 | MIN_CONTRAST_DELTA, 161 | 162 | /* DFT Controls */ 163 | NUM_DFT_WAVES, 164 | POWMAX_MIN, 165 | POWNORM_MIN, 166 | POWMAX_MAX, 167 | FORK_INTERVAL, 168 | FORK_PCT_POWMAX, 169 | FORK_PCT_POWNORM, 170 | 171 | /* Binarization Controls */ 172 | DIRBIN_GRID_W, 173 | DIRBIN_GRID_H, 174 | UNUSED_INT, /* isobin_grid_dim */ 175 | NUM_FILL_HOLES, 176 | 177 | /* Minutiae Detection Controls */ 178 | MAX_MINUTIA_DELTA, 179 | MAX_HIGH_CURVE_THETA, 180 | HIGH_CURVE_HALF_CONTOUR, 181 | MIN_LOOP_LEN, 182 | MIN_LOOP_ASPECT_DIST, 183 | MIN_LOOP_ASPECT_RATIO, 184 | 185 | /* Minutiae Link Controls */ 186 | UNUSED_INT, /* link_table_dim */ 187 | UNUSED_INT, /* max_link_dist */ 188 | UNUSED_INT, /* min_theta_dist */ 189 | MAXTRANS, /* used for removing overlaps as well */ 190 | UNUSED_DBL, /* score_theta_norm */ 191 | UNUSED_DBL, /* score_dist_norm */ 192 | UNUSED_DBL, /* score_dist_weight */ 193 | UNUSED_DBL, /* score_numerator */ 194 | 195 | /* False Minutiae Removal Controls */ 196 | MAX_RMTEST_DIST_V2, 197 | MAX_HOOK_LEN_V2, 198 | MAX_HALF_LOOP_V2, 199 | TRANS_DIR_PIX_V2, 200 | SMALL_LOOP_LEN, 201 | SIDE_HALF_CONTOUR, 202 | INV_BLOCK_MARGIN_V2, 203 | RM_VALID_NBR_MIN, 204 | MAX_OVERLAP_DIST, 205 | MAX_OVERLAP_JOIN_DIST, 206 | MALFORMATION_STEPS_1, 207 | MALFORMATION_STEPS_2, 208 | MIN_MALFORMATION_RATIO, 209 | MAX_MALFORMATION_DIST, 210 | PORES_TRANS_R, 211 | PORES_PERP_STEPS, 212 | PORES_STEPS_FWD, 213 | PORES_STEPS_BWD, 214 | PORES_MIN_DIST2, 215 | PORES_MAX_RATIO, 216 | 217 | /* Ridge Counting Controls */ 218 | MAX_NBRS, 219 | MAX_RIDGE_STEPS 220 | }; 221 | 222 | /* Variables for conducting 8-connected neighbor analyses. */ 223 | /* Pixel neighbor offsets: 0 1 2 3 4 5 6 7 */ /* 7 0 1 */ 224 | int nbr8_dx[] = { 0, 1, 1, 1, 0,-1,-1,-1 }; /* 6 C 2 */ 225 | int nbr8_dy[] = { -1,-1, 0, 1, 1, 1, 0,-1 }; /* 5 4 3 */ 226 | 227 | /* The chain code lookup matrix for 8-connected neighbors. */ 228 | /* Should put this in globals. */ 229 | int chaincodes_nbr8[]={ 3, 2, 1, 230 | 4,-1, 0, 231 | 5, 6, 7}; 232 | 233 | /* Global array of feature pixel pairs. */ 234 | FEATURE_PATTERN feature_patterns[]= 235 | {{RIDGE_ENDING, /* a. Ridge Ending (appearing) */ 236 | APPEARING, 237 | {0,0}, 238 | {0,1}, 239 | {0,0}}, 240 | 241 | {RIDGE_ENDING, /* b. Ridge Ending (disappearing) */ 242 | DISAPPEARING, 243 | {0,0}, 244 | {1,0}, 245 | {0,0}}, 246 | 247 | {BIFURCATION, /* c. Bifurcation (disappearing) */ 248 | DISAPPEARING, 249 | {1,1}, 250 | {0,1}, 251 | {1,1}}, 252 | 253 | {BIFURCATION, /* d. Bifurcation (appearing) */ 254 | APPEARING, 255 | {1,1}, 256 | {1,0}, 257 | {1,1}}, 258 | 259 | {BIFURCATION, /* e. Bifurcation (disappearing) */ 260 | DISAPPEARING, 261 | {1,0}, 262 | {0,1}, 263 | {1,1}}, 264 | 265 | {BIFURCATION, /* f. Bifurcation (disappearing) */ 266 | DISAPPEARING, 267 | {1,1}, 268 | {0,1}, 269 | {1,0}}, 270 | 271 | {BIFURCATION, /* g. Bifurcation (appearing) */ 272 | APPEARING, 273 | {1,1}, 274 | {1,0}, 275 | {0,1}}, 276 | 277 | {BIFURCATION, /* h. Bifurcation (appearing) */ 278 | APPEARING, 279 | {0,1}, 280 | {1,0}, 281 | {1,1}}, 282 | 283 | {BIFURCATION, /* i. Bifurcation (disappearing) */ 284 | DISAPPEARING, 285 | {1,0}, 286 | {0,1}, 287 | {1,0}}, 288 | 289 | {BIFURCATION, /* j. Bifurcation (appearing) */ 290 | APPEARING, 291 | {0,1}, 292 | {1,0}, 293 | {0,1}}}; 294 | -------------------------------------------------------------------------------- /libfprint/nbis/mindtct/line.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | 3 | License: 4 | This software was developed at the National Institute of Standards and 5 | Technology (NIST) by employees of the Federal Government in the course 6 | of their official duties. Pursuant to title 17 Section 105 of the 7 | United States Code, this software is not subject to copyright protection 8 | and is in the public domain. NIST assumes no responsibility whatsoever for 9 | its use by other parties, and makes no guarantees, expressed or implied, 10 | about its quality, reliability, or any other characteristic. 11 | 12 | Disclaimer: 13 | This software was developed to promote biometric standards and biometric 14 | technology testing for the Federal Government in accordance with the USA 15 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 16 | Specific hardware and software products identified in this software were used 17 | in order to perform the software development. In no case does such 18 | identification imply recommendation or endorsement by the National Institute 19 | of Standards and Technology, nor does it imply that the products and equipment 20 | identified are necessarily the best available for the purpose. 21 | 22 | *******************************************************************************/ 23 | 24 | /*********************************************************************** 25 | LIBRARY: LFS - NIST Latent Fingerprint System 26 | 27 | FILE: LINE.C 28 | AUTHOR: Michael D. Garris 29 | DATE: 03/16/1999 30 | 31 | Contains routines that compute contiguous linear trajectories 32 | between two coordinate points required by the NIST Latent 33 | Fingerprint System (LFS). 34 | 35 | *********************************************************************** 36 | ROUTINES: 37 | line_points() 38 | ***********************************************************************/ 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | /************************************************************************* 45 | ************************************************************************** 46 | #cat: line_points - Returns the contiguous coordinates of a line connecting 47 | #cat: 2 specified points. 48 | 49 | Input: 50 | x1 - x-coord of first point 51 | y1 - y-coord of first point 52 | x2 - x-coord of second point 53 | y2 - y-coord of second point 54 | Output: 55 | ox_list - x-coords along line trajectory 56 | oy_list - y-coords along line trajectory 57 | onum - number of points along line trajectory 58 | Return Code: 59 | Zero - successful completion 60 | Negative - system error 61 | **************************************************************************/ 62 | int line_points(int **ox_list, int **oy_list, int *onum, 63 | const int x1, const int y1, const int x2, const int y2) 64 | { 65 | int asize; 66 | int dx, dy, adx, ady; 67 | int x_incr, y_incr; 68 | int i, inx, iny, intx, inty; 69 | double x_factor, y_factor; 70 | double rx, ry; 71 | int ix, iy; 72 | int *x_list, *y_list; 73 | 74 | /* Compute maximum number of points needed to hold line segment. */ 75 | asize = max(abs(x2-x1)+2, abs(y2-y1)+2); 76 | 77 | /* Allocate x and y-pixel coordinate lists to length 'asize'. */ 78 | x_list = (int *)malloc(asize*sizeof(int)); 79 | if(x_list == (int *)NULL){ 80 | fprintf(stderr, "ERROR : line_points : malloc : x_list\n"); 81 | return(-410); 82 | } 83 | y_list = (int *)malloc(asize*sizeof(int)); 84 | if(y_list == (int *)NULL){ 85 | free(x_list); 86 | fprintf(stderr, "ERROR : line_points : malloc : y_list\n"); 87 | return(-411); 88 | } 89 | 90 | /* Compute delta x and y. */ 91 | dx = x2 - x1; 92 | dy = y2 - y1; 93 | 94 | /* Set x and y increments. */ 95 | if(dx >= 0) 96 | x_incr = 1; 97 | else 98 | x_incr = -1; 99 | 100 | if(dy >= 0) 101 | y_incr = 1; 102 | else 103 | y_incr = -1; 104 | 105 | /* Compute |DX| and |DY|. */ 106 | adx = abs(dx); 107 | ady = abs(dy); 108 | 109 | /* Set x-orientation. */ 110 | if(adx > ady) 111 | inx = 1; 112 | else 113 | inx = 0; 114 | 115 | /* Set y-orientation. */ 116 | if(ady > adx) 117 | iny = 1; 118 | else 119 | iny = 0; 120 | 121 | /* CASE 1: |DX| > |DY| */ 122 | /* Increment in X by +-1 */ 123 | /* in Y by +-|DY|/|DX| */ 124 | /* inx = 1 */ 125 | /* iny = 0 */ 126 | /* intx = 1 (inx) */ 127 | /* inty = 0 (iny) */ 128 | /* CASE 2: |DX| < |DY| */ 129 | /* Increment in Y by +-1 */ 130 | /* in X by +-|DX|/|DY| */ 131 | /* inx = 0 */ 132 | /* iny = 1 */ 133 | /* intx = 0 (inx) */ 134 | /* inty = 1 (iny) */ 135 | /* CASE 3: |DX| == |DY| */ 136 | /* inx = 0 */ 137 | /* iny = 0 */ 138 | /* intx = 1 */ 139 | /* inty = 1 */ 140 | intx = 1 - iny; 141 | inty = 1 - inx; 142 | 143 | /* DX */ 144 | /* x_factor = (inx * +-1) + ( iny * ------------ ) */ 145 | /* max(1, |DY|) */ 146 | /* */ 147 | x_factor = (inx * x_incr) + (iny * ((double)dx/max(1, ady))); 148 | 149 | /* DY */ 150 | /* y_factor = (iny * +-1) + ( inx * ------------ ) */ 151 | /* max(1, |DX|) */ 152 | /* */ 153 | y_factor = (iny * y_incr) + (inx * ((double)dy/max(1, adx))); 154 | 155 | /* Initialize integer coordinates. */ 156 | ix = x1; 157 | iy = y1; 158 | /* Set floating point coordinates. */ 159 | rx = (double)x1; 160 | ry = (double)y1; 161 | 162 | /* Initialize to first point in line segment. */ 163 | i = 0; 164 | 165 | /* Assign first point into coordinate list. */ 166 | x_list[i] = x1; 167 | y_list[i++] = y1; 168 | 169 | while((ix != x2) || (iy != y2)){ 170 | 171 | if(i >= asize){ 172 | fprintf(stderr, "ERROR : line_points : coord list overflow\n"); 173 | free(x_list); 174 | free(y_list); 175 | return(-412); 176 | } 177 | 178 | rx += x_factor; 179 | ry += y_factor; 180 | 181 | /* Need to truncate precision so that answers are consistent */ 182 | /* on different computer architectures when truncating doubles. */ 183 | rx = trunc_dbl_precision(rx, TRUNC_SCALE); 184 | ry = trunc_dbl_precision(ry, TRUNC_SCALE); 185 | 186 | /* Compute new x and y-pixel coords in floating point and */ 187 | /* then round to the nearest integer. */ 188 | ix = (intx * (ix + x_incr)) + (iny * (int)(rx + 0.5)); 189 | iy = (inty * (iy + y_incr)) + (inx * (int)(ry + 0.5)); 190 | 191 | /* Assign first point into coordinate list. */ 192 | x_list[i] = ix; 193 | y_list[i++] = iy; 194 | } 195 | 196 | /* Set output pointers. */ 197 | *ox_list = x_list; 198 | *oy_list = y_list; 199 | *onum = i; 200 | 201 | /* Return normally. */ 202 | return(0); 203 | } 204 | -------------------------------------------------------------------------------- /libfprint/nbis/mindtct/log.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | 3 | License: 4 | This software was developed at the National Institute of Standards and 5 | Technology (NIST) by employees of the Federal Government in the course 6 | of their official duties. Pursuant to title 17 Section 105 of the 7 | United States Code, this software is not subject to copyright protection 8 | and is in the public domain. NIST assumes no responsibility whatsoever for 9 | its use by other parties, and makes no guarantees, expressed or implied, 10 | about its quality, reliability, or any other characteristic. 11 | 12 | Disclaimer: 13 | This software was developed to promote biometric standards and biometric 14 | technology testing for the Federal Government in accordance with the USA 15 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 16 | Specific hardware and software products identified in this software were used 17 | in order to perform the software development. In no case does such 18 | identification imply recommendation or endorsement by the National Institute 19 | of Standards and Technology, nor does it imply that the products and equipment 20 | identified are necessarily the best available for the purpose. 21 | 22 | *******************************************************************************/ 23 | 24 | /*********************************************************************** 25 | LIBRARY: LFS - NIST Latent Fingerprint System 26 | 27 | FILE: LOG.C 28 | AUTHOR: Michael D. Garris 29 | DATE: 08/02/1999 30 | 31 | Contains routines responsible for dynamically updating a log file 32 | during the execution of the NIST Latent Fingerprint System (LFS). 33 | 34 | *********************************************************************** 35 | ROUTINES: 36 | open_logfile() 37 | print2log() 38 | close_logfile() 39 | ***********************************************************************/ 40 | 41 | #include 42 | 43 | /* If logging is on, declare global file pointer and supporting */ 44 | /* global variable for logging intermediate results. */ 45 | FILE *logfp; 46 | int avrdir; 47 | float dir_strength; 48 | int nvalid; 49 | 50 | /***************************************************************************/ 51 | /***************************************************************************/ 52 | int open_logfile() 53 | { 54 | #ifdef LOG_REPORT 55 | if((logfp = fopen(LOG_FILE, "wb")) == NULL){ 56 | fprintf(stderr, "ERROR : open_logfile : fopen : %s\n", LOG_FILE); 57 | return(-1); 58 | } 59 | #endif 60 | 61 | return(0); 62 | } 63 | 64 | /***************************************************************************/ 65 | /***************************************************************************/ 66 | void print2log(char *fmt, ...) 67 | { 68 | #ifdef LOG_REPORT 69 | va_list ap; 70 | 71 | va_start(ap, fmt); 72 | vfprintf(logfp, fmt, ap); 73 | va_end(ap); 74 | #endif 75 | } 76 | 77 | /***************************************************************************/ 78 | /***************************************************************************/ 79 | int close_logfile() 80 | { 81 | #ifdef LOG_REPORT 82 | if(fclose(logfp)){ 83 | fprintf(stderr, "ERROR : close_logfile : fclose : %s\n", LOG_FILE); 84 | return(-1); 85 | } 86 | #endif 87 | 88 | return(0); 89 | } 90 | 91 | -------------------------------------------------------------------------------- /libfprint/nbis/mindtct/matchpat.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | 3 | License: 4 | This software was developed at the National Institute of Standards and 5 | Technology (NIST) by employees of the Federal Government in the course 6 | of their official duties. Pursuant to title 17 Section 105 of the 7 | United States Code, this software is not subject to copyright protection 8 | and is in the public domain. NIST assumes no responsibility whatsoever for 9 | its use by other parties, and makes no guarantees, expressed or implied, 10 | about its quality, reliability, or any other characteristic. 11 | 12 | Disclaimer: 13 | This software was developed to promote biometric standards and biometric 14 | technology testing for the Federal Government in accordance with the USA 15 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 16 | Specific hardware and software products identified in this software were used 17 | in order to perform the software development. In no case does such 18 | identification imply recommendation or endorsement by the National Institute 19 | of Standards and Technology, nor does it imply that the products and equipment 20 | identified are necessarily the best available for the purpose. 21 | 22 | *******************************************************************************/ 23 | 24 | /*********************************************************************** 25 | LIBRARY: LFS - NIST Latent Fingerprint System 26 | 27 | FILE: MATCHPAT.C 28 | AUTHOR: Michael D. Garris 29 | DATE: 05/11/1999 30 | UPDATED: 03/16/2005 by MDG 31 | 32 | Contains routines responsible for matching minutia feature 33 | patterns as part of the NIST Latent Fingerprint System (LFS). 34 | 35 | *********************************************************************** 36 | ROUTINES: 37 | match_1st_pair() 38 | match_2nd_pair() 39 | match_3rd_pair() 40 | skip_repeated_horizontal_pair() 41 | skip_repeated_vertical_pair() 42 | ***********************************************************************/ 43 | 44 | #include 45 | #include 46 | 47 | /************************************************************************* 48 | ************************************************************************** 49 | #cat: match_1st_pair - Determines which of the feature_patterns[] have their 50 | #cat: first pixel pair match the specified pixel pair. 51 | 52 | Input: 53 | p1 - first pixel value of pair 54 | p2 - second pixel value of pair 55 | Output: 56 | possible - list of matching feature_patterns[] indices 57 | nposs - number of matches 58 | Return Code: 59 | nposs - number of matches 60 | *************************************************************************/ 61 | int match_1st_pair(unsigned char p1, unsigned char p2, 62 | int *possible, int *nposs) 63 | { 64 | int i; 65 | 66 | /* Set possibilities to 0 */ 67 | *nposs = 0; 68 | 69 | /* Foreach set of feature pairs ... */ 70 | for(i = 0; i < NFEATURES; i++){ 71 | /* If current scan pair matches first pair for feature ... */ 72 | if((p1==feature_patterns[i].first[0]) && 73 | (p2==feature_patterns[i].first[1])){ 74 | /* Store feature as a possible match. */ 75 | possible[*nposs] = i; 76 | /* Bump number of stored possibilities. */ 77 | (*nposs)++; 78 | } 79 | } 80 | 81 | /* Return number of stored possibilities. */ 82 | return(*nposs); 83 | } 84 | 85 | /************************************************************************* 86 | ************************************************************************** 87 | #cat: match_2nd_pair - Determines which of the passed feature_patterns[] have 88 | #cat: their second pixel pair match the specified pixel pair. 89 | 90 | Input: 91 | p1 - first pixel value of pair 92 | p2 - second pixel value of pair 93 | possible - list of potentially-matching feature_patterns[] indices 94 | nposs - number of potential matches 95 | Output: 96 | possible - list of matching feature_patterns[] indices 97 | nposs - number of matches 98 | Return Code: 99 | nposs - number of matches 100 | *************************************************************************/ 101 | int match_2nd_pair(unsigned char p1, unsigned char p2, 102 | int *possible, int *nposs) 103 | { 104 | int i; 105 | int tnposs; 106 | 107 | /* Store input possibilities. */ 108 | tnposs = *nposs; 109 | /* Reset output possibilities to 0. */ 110 | *nposs = 0; 111 | 112 | /* If current scan pair values are the same ... */ 113 | if(p1 == p2) 114 | /* Simply return because pair can't be a second feature pair. */ 115 | return(*nposs); 116 | 117 | /* Foreach possible match based on first pair ... */ 118 | for(i = 0; i < tnposs; i++){ 119 | /* If current scan pair matches second pair for feature ... */ 120 | if((p1==feature_patterns[possible[i]].second[0]) && 121 | (p2==feature_patterns[possible[i]].second[1])){ 122 | /* Store feature as a possible match. */ 123 | possible[*nposs] = possible[i]; 124 | /* Bump number of stored possibilities. */ 125 | (*nposs)++; 126 | } 127 | } 128 | 129 | /* Return number of stored possibilities. */ 130 | return(*nposs); 131 | } 132 | 133 | /************************************************************************* 134 | ************************************************************************** 135 | #cat: match_3rd_pair - Determines which of the passed feature_patterns[] have 136 | #cat: their third pixel pair match the specified pixel pair. 137 | 138 | Input: 139 | p1 - first pixel value of pair 140 | p2 - second pixel value of pair 141 | possible - list of potentially-matching feature_patterns[] indices 142 | nposs - number of potential matches 143 | Output: 144 | possible - list of matching feature_patterns[] indices 145 | nposs - number of matches 146 | Return Code: 147 | nposs - number of matches 148 | *************************************************************************/ 149 | int match_3rd_pair(unsigned char p1, unsigned char p2, 150 | int *possible, int *nposs) 151 | { 152 | int i; 153 | int tnposs; 154 | 155 | /* Store input possibilities. */ 156 | tnposs = *nposs; 157 | /* Reset output possibilities to 0. */ 158 | *nposs = 0; 159 | 160 | /* Foreach possible match based on first and second pairs ... */ 161 | for(i = 0; i < tnposs; i++){ 162 | /* If current scan pair matches third pair for feature ... */ 163 | if((p1==feature_patterns[possible[i]].third[0]) && 164 | (p2==feature_patterns[possible[i]].third[1])){ 165 | /* Store feature as a possible match. */ 166 | possible[*nposs] = possible[i]; 167 | /* Bump number of stored possibilities. */ 168 | (*nposs)++; 169 | } 170 | } 171 | 172 | /* Return number of stored possibilities. */ 173 | return(*nposs); 174 | } 175 | 176 | /************************************************************************* 177 | ************************************************************************** 178 | #cat: skip_repeated_horizontal_pair - Takes the location of two pixel in 179 | #cat: adjacent pixel rows within an image region and skips 180 | #cat: rightward until the either the pixel pair no longer repeats 181 | #cat: itself or the image region is exhausted. 182 | 183 | Input: 184 | cx - current x-coord of starting pixel pair 185 | ex - right edge of the image region 186 | p1ptr - pointer to current top pixel in pair 187 | p2ptr - pointer to current bottom pixel in pair 188 | iw - width (in pixels) of image 189 | ih - height (in pixels) of image 190 | Output: 191 | cx - x-coord of where rightward skip terminated 192 | p1ptr - points to top pixel where rightward skip terminated 193 | p2ptr - points to bottom pixel where rightward skip terminated 194 | *************************************************************************/ 195 | void skip_repeated_horizontal_pair(int *cx, const int ex, 196 | unsigned char **p1ptr, unsigned char **p2ptr, 197 | const int iw, const int ih) 198 | { 199 | int old1, old2; 200 | 201 | /* Store starting pixel pair. */ 202 | old1 = **p1ptr; 203 | old2 = **p2ptr; 204 | 205 | /* Bump horizontally to next pixel pair. */ 206 | (*cx)++; 207 | (*p1ptr)++; 208 | (*p2ptr)++; 209 | 210 | /* While not at right of scan region... */ 211 | while(*cx < ex){ 212 | /* If one or the other pixels in the new pair are different */ 213 | /* from the starting pixel pair... */ 214 | if((**p1ptr != old1) || (**p2ptr != old2)) 215 | /* Done skipping repreated pixel pairs. */ 216 | return; 217 | /* Otherwise, bump horizontally to next pixel pair. */ 218 | (*cx)++; 219 | (*p1ptr)++; 220 | (*p2ptr)++; 221 | } 222 | } 223 | 224 | /************************************************************************* 225 | ************************************************************************** 226 | #cat: skip_repeated_vertical_pair - Takes the location of two pixel in 227 | #cat: adjacent pixel columns within an image region and skips 228 | #cat: downward until the either the pixel pair no longer repeats 229 | #cat: itself or the image region is exhausted. 230 | 231 | Input: 232 | cy - current y-coord of starting pixel pair 233 | ey - bottom of the image region 234 | p1ptr - pointer to current left pixel in pair 235 | p2ptr - pointer to current right pixel in pair 236 | iw - width (in pixels) of image 237 | ih - height (in pixels) of image 238 | Output: 239 | cy - y-coord of where downward skip terminated 240 | p1ptr - points to left pixel where downward skip terminated 241 | p2ptr - points to right pixel where donward skip terminated 242 | *************************************************************************/ 243 | void skip_repeated_vertical_pair(int *cy, const int ey, 244 | unsigned char **p1ptr, unsigned char **p2ptr, 245 | const int iw, const int ih) 246 | { 247 | int old1, old2; 248 | 249 | /* Store starting pixel pair. */ 250 | old1 = **p1ptr; 251 | old2 = **p2ptr; 252 | 253 | /* Bump vertically to next pixel pair. */ 254 | (*cy)++; 255 | (*p1ptr)+=iw; 256 | (*p2ptr)+=iw; 257 | 258 | /* While not at bottom of scan region... */ 259 | while(*cy < ey){ 260 | /* If one or the other pixels in the new pair are different */ 261 | /* from the starting pixel pair... */ 262 | if((**p1ptr != old1) || (**p2ptr != old2)) 263 | /* Done skipping repreated pixel pairs. */ 264 | return; 265 | /* Otherwise, bump vertically to next pixel pair. */ 266 | (*cy)++; 267 | (*p1ptr)+=iw; 268 | (*p2ptr)+=iw; 269 | } 270 | } 271 | 272 | -------------------------------------------------------------------------------- /libfprint/nbis/mindtct/morph.c: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | 3 | License: 4 | This software was developed at the National Institute of Standards and 5 | Technology (NIST) by employees of the Federal Government in the course 6 | of their official duties. Pursuant to title 17 Section 105 of the 7 | United States Code, this software is not subject to copyright protection 8 | and is in the public domain. NIST assumes no responsibility whatsoever for 9 | its use by other parties, and makes no guarantees, expressed or implied, 10 | about its quality, reliability, or any other characteristic. 11 | 12 | Disclaimer: 13 | This software was developed to promote biometric standards and biometric 14 | technology testing for the Federal Government in accordance with the USA 15 | PATRIOT Act and the Enhanced Border Security and Visa Entry Reform Act. 16 | Specific hardware and software products identified in this software were used 17 | in order to perform the software development. In no case does such 18 | identification imply recommendation or endorsement by the National Institute 19 | of Standards and Technology, nor does it imply that the products and equipment 20 | identified are necessarily the best available for the purpose. 21 | 22 | *******************************************************************************/ 23 | 24 | /*********************************************************************** 25 | LIBRARY: LFS - NIST Latent Fingerprint System 26 | 27 | FILE: MORPH.C 28 | AUTHOR: Michael D. Garris 29 | DATE: 10/04/1999 30 | UPDATED: 10/26/1999 by MDG 31 | To avoid indisciminate erosion of pixels along 32 | the edge of the binary image. 33 | UPDATED: 03/16/2005 by MDG 34 | 35 | Contains general support image morphology routines required by 36 | the NIST Latent Fingerprint System (LFS). 37 | 38 | *********************************************************************** 39 | ROUTINES: 40 | erode_charimage_2() 41 | dilate_charimage_2() 42 | get_south8_2() 43 | get_north8_2() 44 | get_east8_2() 45 | get_west8_2() 46 | 47 | ***********************************************************************/ 48 | 49 | #include 50 | #include 51 | 52 | /************************************************************************* 53 | ************************************************************************** 54 | #cat: erode_charimage_2 - Erodes an 8-bit image by setting true pixels to zero 55 | #cat: if any of their 4 neighbors is zero. Allocation of the 56 | #cat: output image is the responsibility of the caller. The 57 | #cat: input image remains unchanged. This routine will NOT 58 | #cat: erode pixels indiscriminately along the image border. 59 | 60 | Input: 61 | inp - input 8-bit image to be eroded 62 | iw - width (in pixels) of image 63 | ih - height (in pixels) of image 64 | Output: 65 | out - contains to the resulting eroded image 66 | **************************************************************************/ 67 | void erode_charimage_2(unsigned char *inp, unsigned char *out, 68 | const int iw, const int ih) 69 | { 70 | int row, col; 71 | unsigned char *itr = inp, *otr = out; 72 | 73 | memcpy(out, inp, iw*ih); 74 | 75 | /* for true pixels. kill pixel if there is at least one false neighbor */ 76 | for ( row = 0 ; row < ih ; row++ ) 77 | for ( col = 0 ; col < iw ; col++ ) 78 | { 79 | if (*itr) /* erode only operates on true pixels */ 80 | { 81 | /* more efficient with C's left to right evaluation of */ 82 | /* conjuctions. E N S functions not executed if W is false */ 83 | if (!(get_west8_2 ((char *)itr, col , 1 ) && 84 | get_east8_2 ((char *)itr, col, iw , 1 ) && 85 | get_north8_2((char *)itr, row, iw , 1 ) && 86 | get_south8_2((char *)itr, row, iw, ih, 1))) 87 | *otr = 0; 88 | } 89 | itr++ ; otr++; 90 | } 91 | } 92 | 93 | /************************************************************************* 94 | ************************************************************************** 95 | #cat: dilate_charimage_2 - Dilates an 8-bit image by setting false pixels to 96 | #cat: one if any of their 4 neighbors is non-zero. Allocation 97 | #cat: of the output image is the responsibility of the caller. 98 | #cat: The input image remains unchanged. 99 | 100 | Input: 101 | inp - input 8-bit image to be dilated 102 | iw - width (in pixels) of image 103 | ih - height (in pixels) of image 104 | Output: 105 | out - contains to the resulting dilated image 106 | **************************************************************************/ 107 | void dilate_charimage_2(unsigned char *inp, unsigned char *out, 108 | const int iw, const int ih) 109 | { 110 | int row, col; 111 | unsigned char *itr = inp, *otr = out; 112 | 113 | memcpy(out, inp, iw*ih); 114 | 115 | /* for all pixels. set pixel if there is at least one true neighbor */ 116 | for ( row = 0 ; row < ih ; row++ ) 117 | for ( col = 0 ; col < iw ; col++ ) 118 | { 119 | if (!*itr) /* pixel is already true, neighbors irrelevant */ 120 | { 121 | /* more efficient with C's left to right evaluation of */ 122 | /* conjuctions. E N S functions not executed if W is false */ 123 | if (get_west8_2 ((char *)itr, col , 0) || 124 | get_east8_2 ((char *)itr, col, iw , 0) || 125 | get_north8_2((char *)itr, row, iw , 0) || 126 | get_south8_2((char *)itr, row, iw, ih, 0)) 127 | *otr = 1; 128 | } 129 | itr++ ; otr++; 130 | } 131 | } 132 | 133 | /************************************************************************* 134 | ************************************************************************** 135 | #cat: get_south8_2 - Returns the value of the 8-bit image pixel 1 below the 136 | #cat: current pixel if defined else it returns (char)0. 137 | 138 | Input: 139 | ptr - points to current pixel in image 140 | row - y-coord of current pixel 141 | iw - width (in pixels) of image 142 | ih - height (in pixels) of image 143 | failcode - return value if desired pixel does not exist 144 | Return Code: 145 | Zero - if neighboring pixel is undefined 146 | (outside of image boundaries) 147 | Pixel - otherwise, value of neighboring pixel 148 | **************************************************************************/ 149 | char get_south8_2(char *ptr, const int row, const int iw, const int ih, 150 | const int failcode) 151 | { 152 | if (row >= ih-1) /* catch case where image is undefined southwards */ 153 | return failcode; /* use plane geometry and return code. */ 154 | 155 | return *(ptr+iw); 156 | } 157 | 158 | /************************************************************************* 159 | ************************************************************************** 160 | #cat: get_north8_2 - Returns the value of the 8-bit image pixel 1 above the 161 | #cat: current pixel if defined else it returns (char)0. 162 | 163 | Input: 164 | ptr - points to current pixel in image 165 | row - y-coord of current pixel 166 | iw - width (in pixels) of image 167 | failcode - return value if desired pixel does not exist 168 | Return Code: 169 | Zero - if neighboring pixel is undefined 170 | (outside of image boundaries) 171 | Pixel - otherwise, value of neighboring pixel 172 | **************************************************************************/ 173 | char get_north8_2(char *ptr, const int row, const int iw, 174 | const int failcode) 175 | { 176 | if (row < 1) /* catch case where image is undefined northwards */ 177 | return failcode; /* use plane geometry and return code. */ 178 | 179 | return *(ptr-iw); 180 | } 181 | 182 | /************************************************************************* 183 | ************************************************************************** 184 | #cat: get_east8_2 - Returns the value of the 8-bit image pixel 1 right of the 185 | #cat: current pixel if defined else it returns (char)0. 186 | 187 | Input: 188 | ptr - points to current pixel in image 189 | col - x-coord of current pixel 190 | iw - width (in pixels) of image 191 | failcode - return value if desired pixel does not exist 192 | Return Code: 193 | Zero - if neighboring pixel is undefined 194 | (outside of image boundaries) 195 | Pixel - otherwise, value of neighboring pixel 196 | **************************************************************************/ 197 | char get_east8_2(char *ptr, const int col, const int iw, 198 | const int failcode) 199 | { 200 | if (col >= iw-1) /* catch case where image is undefined eastwards */ 201 | return failcode; /* use plane geometry and return code. */ 202 | 203 | return *(ptr+ 1); 204 | } 205 | 206 | /************************************************************************* 207 | ************************************************************************** 208 | #cat: get_west8_2 - Returns the value of the 8-bit image pixel 1 left of the 209 | #cat: current pixel if defined else it returns (char)0. 210 | 211 | Input: 212 | ptr - points to current pixel in image 213 | col - x-coord of current pixel 214 | failcode - return value if desired pixel does not exist 215 | Return Code: 216 | Zero - if neighboring pixel is undefined 217 | (outside of image boundaries) 218 | Pixel - otherwise, value of neighboring pixel 219 | **************************************************************************/ 220 | char get_west8_2(char *ptr, const int col, const int failcode) 221 | { 222 | if (col < 1) /* catch case where image is undefined westwards */ 223 | return failcode; /* use plane geometry and return code. */ 224 | 225 | return *(ptr- 1); 226 | } 227 | --------------------------------------------------------------------------------