fingerprint-ruby 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/ext/fingerprint/compare/compare.cpp +58 -0
- data/ext/fingerprint/compare/compare.h +31 -0
- data/ext/fingerprint/extconf.rb +19 -0
- data/ext/fingerprint/fingerprint.cpp +77 -0
- data/ext/fingerprint/u_are_u/dpfj.h +963 -0
- data/ext/fingerprint/u_are_u/dpfpdd.h +626 -0
- data/lib/fingerprint.rb +2 -0
- data/lib/u_are_u/lib32/libdpfj.so +0 -0
- data/lib/u_are_u/lib32/libdpfj.so.2 +0 -0
- data/lib/u_are_u/lib32/libdpfj.so.2.0.1 +0 -0
- data/lib/u_are_u/lib32/libdpfpdd.so +0 -0
- data/lib/u_are_u/lib32/libdpfpdd.so.2 +0 -0
- data/lib/u_are_u/lib32/libdpfpdd.so.2.0.1 +0 -0
- data/lib/u_are_u/lib64/libdpfj.so +0 -0
- data/lib/u_are_u/lib64/libdpfj.so.2 +0 -0
- data/lib/u_are_u/lib64/libdpfj.so.2.0.1 +0 -0
- data/lib/u_are_u/lib64/libdpfpdd.so +0 -0
- data/lib/u_are_u/lib64/libdpfpdd.so.2 +0 -0
- data/lib/u_are_u/lib64/libdpfpdd.so.2.0.1 +0 -0
- data/lib/u_are_u/library.rb +5 -0
- metadata +63 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MjA4YmM3MWJkODZiYzU4NzQ2MjMxOWU0MzhjNGFkNDIyYmNmMTJiNw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NDkyZGQzZTdkZDI0YTU2NzlhNzAwYTRiMDk4NTU1Njg1N2VjY2IzNg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MWJiODhiOTE2ZDA5Y2ZhNGFiYTdjMjg4MjZjNmUzZmFmMWRlMGNiYjhiNTU5
|
10
|
+
NmM2M2E2NGQzNzk5MDM2YTZlZGJkMTAwNjljYWJmZjExODM0MGI1YTFjYmQ2
|
11
|
+
ODViMDEwYzUxNTRhOTRiY2I2ZTczYzc1MjI0MDVhODU1ZTlmZDA=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZDE4ODY3OGFhOGFhNzgzNTg2NWJjOTgwOGY5MWExNTY2ODE5YTBmY2I0ZDM4
|
14
|
+
ZTgzYWFlMWVmMjQyYTg3MDMxZGEyYzRjMzEyODI0MzQxMDFhMzE1M2EyYWM3
|
15
|
+
ODlkZDM1ZDNjZWZmYWJiYThmOGM2MTZkNmIwMjg5NDEwZDQzMjE=
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#include <iostream>
|
2
|
+
#include <fstream>
|
3
|
+
#include <unistd.h>
|
4
|
+
#include "compare.h"
|
5
|
+
|
6
|
+
using namespace std;
|
7
|
+
|
8
|
+
bool VerifyUser( std::string db_file,
|
9
|
+
std::string print_file) {
|
10
|
+
unsigned char *dbFmd = NULL, *printFmd = NULL;
|
11
|
+
unsigned int dbFmdSize = 0, printFmdSize = 0;
|
12
|
+
|
13
|
+
LoadPrint(db_file, &dbFmd, &dbFmdSize);
|
14
|
+
LoadPrint(print_file, &printFmd, &printFmdSize);
|
15
|
+
|
16
|
+
return VerifyUser(dbFmd, dbFmdSize, printFmd, printFmdSize);
|
17
|
+
}
|
18
|
+
|
19
|
+
bool VerifyUser( unsigned char* dbPrint,
|
20
|
+
unsigned int dbPrintSize,
|
21
|
+
unsigned char* print,
|
22
|
+
unsigned int printSize) {
|
23
|
+
|
24
|
+
// Only compare if both fingerprints have data
|
25
|
+
if(dbPrintSize > 0 && printSize > 0) {
|
26
|
+
unsigned int falsematch_rate;
|
27
|
+
int result = dpfj_compare(DPFJ_FMD_ANSI_378_2004, dbPrint, dbPrintSize, 0,
|
28
|
+
DPFJ_FMD_ANSI_378_2004, print, printSize, 0, &falsematch_rate);
|
29
|
+
|
30
|
+
// If the comparison was successful and the prints matched
|
31
|
+
if(result == DPFJ_SUCCESS && falsematch_rate < TARGET_FALSEMATCH_RATE) {
|
32
|
+
return true;
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
return false;
|
37
|
+
}
|
38
|
+
|
39
|
+
void LoadPrint( std::string file,
|
40
|
+
unsigned char** print,
|
41
|
+
unsigned int* printSize) {
|
42
|
+
|
43
|
+
// Open the file in binary mode
|
44
|
+
ifstream input(file.c_str(), ios::in | ios::binary | ios::ate);
|
45
|
+
|
46
|
+
// Only try if the file exists
|
47
|
+
if(input.is_open()) {
|
48
|
+
// Figure out the file size and allocate memory
|
49
|
+
// for the data
|
50
|
+
*printSize = (unsigned int) input.tellg();
|
51
|
+
*print = new unsigned char[*printSize];
|
52
|
+
|
53
|
+
// Read the file data from the beginning
|
54
|
+
input.seekg(0, ios::beg);
|
55
|
+
input.read((char*) (*print), *printSize);
|
56
|
+
input.close();
|
57
|
+
}
|
58
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
/*
|
2
|
+
* Provides methods needed to compare fingerprints.
|
3
|
+
*/
|
4
|
+
|
5
|
+
#ifndef COMPARE_H_
|
6
|
+
#define COMPARE_H_
|
7
|
+
|
8
|
+
#include <string>
|
9
|
+
#include <dpfj.h>
|
10
|
+
#include <dpfpdd.h>
|
11
|
+
|
12
|
+
// Target accuracy of fingerprint comparison
|
13
|
+
#define TARGET_FALSEMATCH_RATE (DPFJ_PROBABILITY_ONE / 100000)
|
14
|
+
|
15
|
+
// Compares the fingerprints in the two provided files
|
16
|
+
bool VerifyUser( std::string db_file,
|
17
|
+
std::string print_file);
|
18
|
+
|
19
|
+
// Compares the fingerprints in the two provided buffers
|
20
|
+
bool VerifyUser( unsigned char* dbPrint,
|
21
|
+
unsigned int dbPrintSize,
|
22
|
+
unsigned char* print,
|
23
|
+
unsigned int printSize);
|
24
|
+
|
25
|
+
// Loads a fingerprint from the specified file into the
|
26
|
+
// supplied buffer
|
27
|
+
void LoadPrint( std::string file,
|
28
|
+
unsigned char** print,
|
29
|
+
unsigned int* printSize);
|
30
|
+
|
31
|
+
#endif /*COMPARE_H_*/
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
def bits
|
4
|
+
['bits'].pack('p').size * 8
|
5
|
+
end
|
6
|
+
|
7
|
+
library_dir = File.realpath(File.join(File.dirname(__FILE__), '..', '..', 'lib', 'u_are_u', "lib#{bits}"))
|
8
|
+
|
9
|
+
dir_config('', 'compare', 'compare')
|
10
|
+
dir_config('', 'u_are_u', 'u_are_u')
|
11
|
+
dir_config('', library_dir, library_dir)
|
12
|
+
|
13
|
+
have_library('dpfj') or raise
|
14
|
+
have_library('dpfpdd') or raise
|
15
|
+
have_library('stdc++') or raise
|
16
|
+
|
17
|
+
$objs = ['fingerprint.o', 'compare/compare.o']
|
18
|
+
|
19
|
+
create_makefile('keyme/fingerprint')
|
@@ -0,0 +1,77 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
|
3
|
+
#include "ruby.h"
|
4
|
+
#include "compare/compare.h"
|
5
|
+
|
6
|
+
VALUE verify_user_wrapper(VALUE self, VALUE db_print, VALUE check_print) {
|
7
|
+
bool result;
|
8
|
+
unsigned char *db, *check;
|
9
|
+
unsigned int db_len, check_len;
|
10
|
+
|
11
|
+
Check_Type(db_print, T_ARRAY);
|
12
|
+
Check_Type(check_print, T_ARRAY);
|
13
|
+
|
14
|
+
db_len = RARRAY_LEN(db_print);
|
15
|
+
check_len = RARRAY_LEN(check_print);
|
16
|
+
|
17
|
+
db = (unsigned char*) malloc(db_len);
|
18
|
+
check = (unsigned char*) malloc(check_len);
|
19
|
+
|
20
|
+
for(unsigned int i = 0; i < db_len; i++) {
|
21
|
+
db[i] = NUM2UINT(rb_ary_entry(db_print, i));
|
22
|
+
}
|
23
|
+
for(unsigned int i = 0; i < check_len; i++) {
|
24
|
+
check[i] = NUM2UINT(rb_ary_entry(check_print, i));
|
25
|
+
}
|
26
|
+
|
27
|
+
result = VerifyUser(db, db_len, check, check_len);
|
28
|
+
|
29
|
+
free(db);
|
30
|
+
free(check);
|
31
|
+
|
32
|
+
return result ? Qtrue : Qfalse;
|
33
|
+
}
|
34
|
+
|
35
|
+
VALUE load_print_wrapper(VALUE self, VALUE path) {
|
36
|
+
VALUE result;
|
37
|
+
unsigned char *print;
|
38
|
+
unsigned int printSize;
|
39
|
+
|
40
|
+
Check_Type(path, T_STRING);
|
41
|
+
LoadPrint(RSTRING_PTR(path), &print, &printSize);
|
42
|
+
|
43
|
+
result = rb_ary_new();
|
44
|
+
for(unsigned int i = 0; i < printSize; i++) {
|
45
|
+
rb_ary_push(result, UINT2NUM(print[i]));
|
46
|
+
}
|
47
|
+
|
48
|
+
free(print);
|
49
|
+
|
50
|
+
return result;
|
51
|
+
}
|
52
|
+
|
53
|
+
VALUE rb_mKeyMe;
|
54
|
+
VALUE rb_mFingerprint;
|
55
|
+
|
56
|
+
extern "C" {
|
57
|
+
void Init_fingerprint() {
|
58
|
+
rb_mKeyMe = rb_define_module("KeyMe");
|
59
|
+
rb_mFingerprint = rb_define_module_under(
|
60
|
+
rb_mKeyMe,
|
61
|
+
"Fingerprint"
|
62
|
+
);
|
63
|
+
|
64
|
+
rb_define_singleton_method(
|
65
|
+
rb_mFingerprint,
|
66
|
+
"verify_user",
|
67
|
+
RUBY_METHOD_FUNC(verify_user_wrapper),
|
68
|
+
2
|
69
|
+
);
|
70
|
+
rb_define_singleton_method(
|
71
|
+
rb_mFingerprint,
|
72
|
+
"load_print",
|
73
|
+
RUBY_METHOD_FUNC(load_print_wrapper),
|
74
|
+
1
|
75
|
+
);
|
76
|
+
}
|
77
|
+
}
|
@@ -0,0 +1,963 @@
|
|
1
|
+
/**
|
2
|
+
\file dpfj.h
|
3
|
+
|
4
|
+
\copyright (c) 2011 DigitalPersona, Inc
|
5
|
+
|
6
|
+
\brief U.are.U SDK FingerJet Engine API
|
7
|
+
|
8
|
+
Data types and functions for feature extraction, matching and conversion.
|
9
|
+
|
10
|
+
\version 2.0.0
|
11
|
+
*/
|
12
|
+
|
13
|
+
#ifndef __DPFJ_H__
|
14
|
+
#define __DPFJ_H__
|
15
|
+
|
16
|
+
|
17
|
+
/** \cond NEVER */
|
18
|
+
#ifndef NULL
|
19
|
+
# define NULL 0
|
20
|
+
#endif
|
21
|
+
|
22
|
+
#ifndef DPERROR
|
23
|
+
# define _DP_FACILITY 0x05BA
|
24
|
+
# define DPERROR(err) ((int)err | (_DP_FACILITY << 16))
|
25
|
+
#endif /* DPERROR */
|
26
|
+
|
27
|
+
#define DPFJ_API_VERSION_MAJOR 1
|
28
|
+
#define DPFJ_API_VERSION_MINOR 0
|
29
|
+
/** \endcond */
|
30
|
+
|
31
|
+
|
32
|
+
/****************************************************************************************************
|
33
|
+
Error codes
|
34
|
+
****************************************************************************************************/
|
35
|
+
|
36
|
+
/**
|
37
|
+
\brief API call succeeded.
|
38
|
+
*/
|
39
|
+
#define DPFJ_SUCCESS 0
|
40
|
+
|
41
|
+
/**
|
42
|
+
\brief API call is not implemented.
|
43
|
+
*/
|
44
|
+
#define DPFJ_E_NOT_IMPLEMENTED DPERROR(10)
|
45
|
+
|
46
|
+
/**
|
47
|
+
\brief Unspecified failure.
|
48
|
+
|
49
|
+
"Catch-all" generic failure code. Can be returned by all API calls in case of failure, when the reason for the failure is unknown or cannot be specified.
|
50
|
+
*/
|
51
|
+
#define DPFJ_E_FAILURE DPERROR(11)
|
52
|
+
|
53
|
+
/**
|
54
|
+
\brief No data is available.
|
55
|
+
*/
|
56
|
+
#define DPFJ_E_NO_DATA DPERROR(12)
|
57
|
+
|
58
|
+
/**
|
59
|
+
\brief Memory allocated by application is not enough to contain data which is expected.
|
60
|
+
*/
|
61
|
+
#define DPFJ_E_MORE_DATA DPERROR(13)
|
62
|
+
|
63
|
+
/**
|
64
|
+
\brief One or more parameters passed to the API call are invalid.
|
65
|
+
*/
|
66
|
+
#define DPFJ_E_INVALID_PARAMETER DPERROR(20)
|
67
|
+
|
68
|
+
/**
|
69
|
+
\brief FID is invalid.
|
70
|
+
*/
|
71
|
+
#define DPFJ_E_INVALID_FID DPERROR(101)
|
72
|
+
|
73
|
+
/**
|
74
|
+
\brief Image is too small.
|
75
|
+
*/
|
76
|
+
#define DPFJ_E_TOO_SMALL_AREA DPERROR(102)
|
77
|
+
|
78
|
+
/**
|
79
|
+
\brief FMD is invalid.
|
80
|
+
*/
|
81
|
+
#define DPFJ_E_INVALID_FMD DPERROR(201)
|
82
|
+
|
83
|
+
/**
|
84
|
+
\brief Enrollment operation is in progress.
|
85
|
+
*/
|
86
|
+
#define DPFJ_E_ENROLLMENT_IN_PROGRESS DPERROR(301)
|
87
|
+
|
88
|
+
/**
|
89
|
+
\brief Enrollment operation has not begun.
|
90
|
+
*/
|
91
|
+
#define DPFJ_E_ENROLLMENT_NOT_STARTED DPERROR(302)
|
92
|
+
|
93
|
+
/**
|
94
|
+
\brief Not enough in the pool of FMDs to create enrollment FMD.
|
95
|
+
*/
|
96
|
+
#define DPFJ_E_ENROLLMENT_NOT_READY DPERROR(303)
|
97
|
+
|
98
|
+
/****************************************************************************************************
|
99
|
+
Data types and definitions
|
100
|
+
****************************************************************************************************/
|
101
|
+
|
102
|
+
/**
|
103
|
+
\brief Normalized value when probability = 1.
|
104
|
+
*/
|
105
|
+
#define DPFJ_PROBABILITY_ONE 0x7fffffff
|
106
|
+
|
107
|
+
/**
|
108
|
+
\brief Fingerprint Image Data (FID) Format.
|
109
|
+
*/
|
110
|
+
typedef int DPFJ_FID_FORMAT;
|
111
|
+
|
112
|
+
#define DPFJ_FID_ANSI_381_2004 0x001B0401 /**< ANSI INSITS 381-2004 format */
|
113
|
+
#define DPFJ_FID_ISO_19794_4_2005 0x01010007 /**< ISO IEC 19794-4-2005 format */
|
114
|
+
|
115
|
+
/**
|
116
|
+
\brief Fingerptint Minutiae Data (FMD) Format.
|
117
|
+
*/
|
118
|
+
typedef int DPFJ_FMD_FORMAT;
|
119
|
+
|
120
|
+
#define DPFJ_FMD_ANSI_378_2004 0x001B0001 /**< ANSI INSITS 378-2004 Fingerprint Minutiae Data format */
|
121
|
+
#define DPFJ_FMD_ISO_19794_2_2005 0x01010001 /**< ISO IEC 19794-2-2005 Fingerprint Minutiae Data format */
|
122
|
+
#define DPFJ_FMD_DP_PRE_REG_FEATURES 0 /**< deprecated DigitalPersona pre-registration feature set format */
|
123
|
+
#define DPFJ_FMD_DP_REG_FEATURES 1 /**< deprecated DigitalPersona registration template format */
|
124
|
+
#define DPFJ_FMD_DP_VER_FEATURES 2 /**< deprecated DigitalPersona verification feature set format */
|
125
|
+
|
126
|
+
/** \brief Defines finger position.
|
127
|
+
|
128
|
+
Finger position according to ANSI 378-2004 and ISO 19794-2-2005 standards.
|
129
|
+
*/
|
130
|
+
typedef int DPFJ_FINGER_POSITION;
|
131
|
+
|
132
|
+
#define DPFJ_POSITION_UNKNOWN 0 /**< position unknown */
|
133
|
+
#define DPFJ_POSITION_RTHUMB 1 /**< right thumb */
|
134
|
+
#define DPFJ_POSITION_RINDEX 2 /**< right index finger */
|
135
|
+
#define DPFJ_POSITION_RMIDDLE 3 /**< right middle finger */
|
136
|
+
#define DPFJ_POSITION_RRING 4 /**< right ring finger */
|
137
|
+
#define DPFJ_POSITION_RLITTLE 5 /**< right little finger */
|
138
|
+
#define DPFJ_POSITION_LTHUMB 6 /**< left thumb */
|
139
|
+
#define DPFJ_POSITION_LINDEX 7 /**< left index finger */
|
140
|
+
#define DPFJ_POSITION_LMIDDLE 8 /**< left middle finger */
|
141
|
+
#define DPFJ_POSITION_LRING 9 /**< left ring finger */
|
142
|
+
#define DPFJ_POSITION_LLITTLE 10 /**< left little finger */
|
143
|
+
|
144
|
+
/**
|
145
|
+
\brief Defines impression type.
|
146
|
+
|
147
|
+
Impression type according to ANSI 378-2004 and ISO 19794-2-2005 standards
|
148
|
+
*/
|
149
|
+
typedef int DPFJ_SCAN_TYPE;
|
150
|
+
|
151
|
+
#define DPFJ_SCAN_LIVE_PLAIN 0
|
152
|
+
#define DPFJ_SCAN_LIVE_ROLLED 1
|
153
|
+
#define DPFJ_SCAN_NONLIVE_PLAIN 2
|
154
|
+
#define DPFJ_SCAN_NONLIVE_ROLLED 3
|
155
|
+
#define DPFJ_SCAN_SWIPE 8
|
156
|
+
|
157
|
+
|
158
|
+
/** \cond NEVER */
|
159
|
+
#define DPFJ_FID_ANSI_381_2004_RECORD_HEADER_LENGTH 36
|
160
|
+
#define DPFJ_FID_ISO_19794_4_2005_RECORD_HEADER_LENGTH 32
|
161
|
+
#define DPFJ_FID_ANSI_ISO_VIEW_HEADER_LENGTH 14
|
162
|
+
|
163
|
+
#define DPFJ_FMD_ANSI_378_2004_RECORD_HEADER_LENGTH 26
|
164
|
+
#define DPFJ_FMD_ISO_19794_2_2005_RECORD_HEADER_LENGTH 24
|
165
|
+
#define DPFJ_FMD_ANSI_ISO_VIEW_HEADER_LENGTH 4
|
166
|
+
#define DPFJ_FMD_ANSI_ISO_MINITIA_LENGTH 6
|
167
|
+
/** \endcond */
|
168
|
+
|
169
|
+
/**
|
170
|
+
\brief Maximum size of a single-view FMD with no extended data block.
|
171
|
+
*/
|
172
|
+
#define MAX_FMD_SIZE (DPFJ_FMD_ANSI_378_2004_RECORD_HEADER_LENGTH + DPFJ_FMD_ANSI_ISO_VIEW_HEADER_LENGTH + 255 * DPFJ_FMD_ANSI_ISO_MINITIA_LENGTH + 2)
|
173
|
+
|
174
|
+
/**
|
175
|
+
\brief API Version information.
|
176
|
+
*/
|
177
|
+
typedef struct dpfj_ver_info {
|
178
|
+
int major; /**< major version number */
|
179
|
+
int minor; /**< minor version number */
|
180
|
+
int maintanance; /**< maintanance or revision number */
|
181
|
+
} DPFJ_VER_INFO;
|
182
|
+
|
183
|
+
/**
|
184
|
+
\brief Complete information about library/SDK.
|
185
|
+
*/
|
186
|
+
typedef struct dpfj_version {
|
187
|
+
unsigned int size; /**< Size of the structure, in bytes */
|
188
|
+
DPFJ_VER_INFO lib_ver; /**< file version of the library/SDK */
|
189
|
+
DPFJ_VER_INFO api_ver; /**< version of the API */
|
190
|
+
} DPFJ_VERSION;
|
191
|
+
|
192
|
+
/**
|
193
|
+
\brief Candidate, result of identification.
|
194
|
+
*/
|
195
|
+
typedef struct dpfj_candidate{
|
196
|
+
unsigned int size; /**< size of the structure, in bytes */
|
197
|
+
unsigned int fmd_idx; /**< index of the FMD in the input array */
|
198
|
+
unsigned int view_idx; /**< index of the view in the FMD */
|
199
|
+
} DPFJ_CANDIDATE;
|
200
|
+
|
201
|
+
|
202
|
+
/****************************************************************************************************
|
203
|
+
API calls
|
204
|
+
****************************************************************************************************/
|
205
|
+
|
206
|
+
#ifdef __cplusplus
|
207
|
+
extern "C" {
|
208
|
+
#endif /* __cplusplus */
|
209
|
+
|
210
|
+
/**
|
211
|
+
\brief Query the library and API version information.
|
212
|
+
|
213
|
+
\param ver [in] Pointer to the empty structure (per DPFJ_VERSION); [out] Pointer to structure containing version information
|
214
|
+
\return DPFJ_SUCCESS: Version information was acquired;
|
215
|
+
\return DPFJ_E_FAILURE: Failed to acquire version information.
|
216
|
+
*/
|
217
|
+
int dpfj_version(
|
218
|
+
DPFJ_VERSION* ver
|
219
|
+
);
|
220
|
+
|
221
|
+
|
222
|
+
/**
|
223
|
+
\brief Extracts features and creates an FMD from a raw image.
|
224
|
+
|
225
|
+
When you do a fingerprint capture, you can receive a raw image or a FID. If you specify a raw image, you can then extract features into an FMD using this function.
|
226
|
+
The raw image is just a buffer of pixels. This function works with raw images that have
|
227
|
+
- 8 bits per pixel
|
228
|
+
- no padding
|
229
|
+
- square pixels (dpi is the same for horizontal and vertical)
|
230
|
+
|
231
|
+
The size of the resulting FMD will vary depending on the minutiae in a specific fingerprint. The maximum possible size of a single-view FMD is MAX_FMD_SIZE.
|
232
|
+
If the value pointed to by fmd_size is zero, the function will return with the error code DPFJ_E_MORE_DATA and the required size will be stored in the
|
233
|
+
value pointed to by fmd_size. In order to determine the size, this function processes the image, extracts features and discards the FMD, so it takes significant
|
234
|
+
processing time. However if memory shortages are a key issue, this allows you to allocate memory more efficiently at the expense of processing time.
|
235
|
+
If memory is available, you will get the best performance if you always allocate MAX_FMD_SIZE for the FMD.
|
236
|
+
The value pointed to by fmd_size will always be returned as the actual size of the FMD that was extracted.
|
237
|
+
|
238
|
+
\param image_data pointer to the image data
|
239
|
+
\param image_size size of the image data
|
240
|
+
\param image_width width of the image
|
241
|
+
\param image_height height of the image
|
242
|
+
\param image_dpi resolution of the image
|
243
|
+
\param finger_pos position of the finger
|
244
|
+
\param cbeff_id CBEFF product ID, from IBIA registry
|
245
|
+
\param fmd_type type of the FMD
|
246
|
+
\param fmd pointer to recieve FMD
|
247
|
+
\param fmd_size pointer to allocated size for the FMD, pointer to receive the actual size of the FMD
|
248
|
+
\return DPFJ_SUCCESS: FMD was created;
|
249
|
+
\return DPFJ_E_MORE_DATA: Features extracted, but allocated memory is not sufficient for FMD. The required memory size is in the fmd_size.
|
250
|
+
\return DPFJ_E_INVALID_PARAMETER: One or more parameters passed are invalid.
|
251
|
+
\return DPFJ_E_FAILURE: Failed to create FMD.
|
252
|
+
*/
|
253
|
+
int dpfj_create_fmd_from_raw (
|
254
|
+
const unsigned char* image_data,
|
255
|
+
unsigned int image_size,
|
256
|
+
unsigned int image_width,
|
257
|
+
unsigned int image_height,
|
258
|
+
unsigned int image_dpi,
|
259
|
+
DPFJ_FINGER_POSITION finger_pos,
|
260
|
+
unsigned int cbeff_id,
|
261
|
+
DPFJ_FMD_FORMAT fmd_type,
|
262
|
+
unsigned char* fmd,
|
263
|
+
unsigned int* fmd_size
|
264
|
+
);
|
265
|
+
|
266
|
+
/**
|
267
|
+
\brief Extracts features and creates an FMD from an ANSI or ISO image.
|
268
|
+
|
269
|
+
This function works with FIDs that have
|
270
|
+
- 8 bits per pixel
|
271
|
+
- no padding
|
272
|
+
- square pixels (dpi is the same for horizontal and vertical)
|
273
|
+
The size of the resulting FMD will vary depending on the minutiae in a specific fingerprint. The maximum possible size of a single-view FMD is MAX_FMD_SIZE.
|
274
|
+
If the value pointed to by fmd_size is zero, the function will return with the error code DPFJ_E_MORE_DATA and the required size will be stored in the value
|
275
|
+
pointed to by fmd_size. In order to determine the size, this function processes the image, extracts the FMD and discards the FMD, so it takes significant processing time.
|
276
|
+
However if memory shortages are a key issue, this allows you to allocate memory more efficiently at the expense of processing time.
|
277
|
+
If memory is available, you will get the best performance if you always allocate MAX_FMD_SIZE for the FMD.
|
278
|
+
The value pointed to by fmd_size will always be returned as the actual size of the FMD that was extracted.
|
279
|
+
|
280
|
+
\param fid_type type of the FID
|
281
|
+
\param fid pointer to the FID data
|
282
|
+
\param fid_size size of the FID data
|
283
|
+
\param fmd_type type of the FMD
|
284
|
+
\param fmd pointer to recieve FMD data
|
285
|
+
\param fmd_size pointer to allocated size for the FMD, pointer to receive the actual size of the FMD
|
286
|
+
\return DPFJ_SUCCESS: FMD was created;
|
287
|
+
\return DPFJ_E_MORE_DATA: Features extracted, but allocated memory is not sufficient for FMD. The required memory size is in the fmd_size.
|
288
|
+
\return DPFJ_E_INVALID_PARAMETER: One or more parameters passed are invalid.
|
289
|
+
\return DPFJ_E_FAILURE: Failed to create FMD.
|
290
|
+
*/
|
291
|
+
int dpfj_create_fmd_from_fid (
|
292
|
+
DPFJ_FID_FORMAT fid_type,
|
293
|
+
const unsigned char* fid,
|
294
|
+
unsigned int fid_size,
|
295
|
+
DPFJ_FMD_FORMAT fmd_type,
|
296
|
+
unsigned char* fmd,
|
297
|
+
unsigned int* fmd_size
|
298
|
+
);
|
299
|
+
|
300
|
+
/**
|
301
|
+
\brief Compares two fingerprints.
|
302
|
+
|
303
|
+
Given two single views from two FMDs, this function returns a <b>dissimilarity score</b> indicating the quality of the match.
|
304
|
+
The dissimilarity scores returned values are between:
|
305
|
+
0=match
|
306
|
+
maxint=no match
|
307
|
+
Values close to 0 indicate very close matches, values closer to maxint indicate very poor matches.
|
308
|
+
For a discussion of how to evaluate dissimilarity scores, as well as the statistical validity of the dissimilarity score and error rates, consult the Developer Guide.
|
309
|
+
The dpfj_compare function returns DPFJ_SUCCESS if it is able to compare the fingerprints successfully (i.e., the FMDs are valid and correctly formed).
|
310
|
+
However that does not mean that the fingerprints matched. To check whether they matched, you must look at the dissimilarity score.
|
311
|
+
|
312
|
+
\param fmd1_type type of the first FMD
|
313
|
+
\param fmd1 pointer to the first FMD
|
314
|
+
\param fmd1_size size of the first FMD
|
315
|
+
\param fmd1_view_idx index of the view
|
316
|
+
\param fmd2_type type of the second FMD
|
317
|
+
\param fmd2 pointer to the second FMD
|
318
|
+
\param fmd2_size size of the second FMD
|
319
|
+
\param fmd2_view_idx index of the view
|
320
|
+
\param score pointer to receive dissimilarity score
|
321
|
+
\return DPFJ_SUCCESS: Comparison finished;
|
322
|
+
\return DPFJ_E_FAILURE: Unknown error.
|
323
|
+
*/
|
324
|
+
int dpfj_compare(
|
325
|
+
DPFJ_FMD_FORMAT fmd1_type,
|
326
|
+
unsigned char* fmd1,
|
327
|
+
unsigned int fmd1_size,
|
328
|
+
unsigned int fmd1_view_idx,
|
329
|
+
DPFJ_FMD_FORMAT fmd2_type,
|
330
|
+
unsigned char* fmd2,
|
331
|
+
unsigned int fmd2_size,
|
332
|
+
unsigned int fmd2_view_idx,
|
333
|
+
unsigned int* score
|
334
|
+
);
|
335
|
+
|
336
|
+
/**
|
337
|
+
\brief Compares a single fingerprint to an array of fingerprints.
|
338
|
+
|
339
|
+
This function takes as inputs:
|
340
|
+
- a single view in an FMD
|
341
|
+
- an array of FMDs (each FMD can contain up to 16 views) to compare
|
342
|
+
- the desired number of candidates to return
|
343
|
+
- the threshold for False Positive Identification Rate that is permitted
|
344
|
+
This function compares a single view against an array of FMDs. Each time view has a score lower than the threshold, that view is marked as a possible candidate.
|
345
|
+
Then when all possible candidates are identified (i.e., they meet the threshold), they are ranked by their score. Finally, the function returns as many
|
346
|
+
candidates as requested, based on the candidates with the lowest dissimilarity score.
|
347
|
+
For a discussion of setting the threshold as well as the statistical validity of the dissimilarity score and error rates, consult the Developer Guide.
|
348
|
+
|
349
|
+
\param fmd1_type type of the FMDs
|
350
|
+
\param fmd1 pointer to the first FMD data
|
351
|
+
\param fmd1_size size of the first FMD data
|
352
|
+
\param fmd1_view_idx index of the view
|
353
|
+
\param fmds_type type of the FMDs in the fmds array
|
354
|
+
\param fmds_cnt number of FMDs in the fmds array
|
355
|
+
\param fmds array of FMDs
|
356
|
+
\param fmds_size array of sizes of the FMDs data
|
357
|
+
\param threshold_score target threshold on degree of dissimilarity
|
358
|
+
\param candidate_cnt [in] number of allocated entries in the candidates array; [out] receives the actual number of candidates filled in the array as a result of identification
|
359
|
+
\param candidates array of candidates
|
360
|
+
\return DPFJ_SUCESS: Identification finished;
|
361
|
+
\return DPFJ_E_FAILURE: Unknown error.
|
362
|
+
*/
|
363
|
+
int dpfj_identify(
|
364
|
+
DPFJ_FMD_FORMAT fmd1_type,
|
365
|
+
unsigned char* fmd1,
|
366
|
+
unsigned int fmd1_size,
|
367
|
+
unsigned int fmd1_view_idx,
|
368
|
+
DPFJ_FMD_FORMAT fmds_type,
|
369
|
+
unsigned int fmds_cnt,
|
370
|
+
unsigned char** fmds,
|
371
|
+
unsigned int* fmds_size,
|
372
|
+
unsigned int threshold_score,
|
373
|
+
unsigned int* candidate_cnt,
|
374
|
+
DPFJ_CANDIDATE* candidates
|
375
|
+
);
|
376
|
+
|
377
|
+
/**
|
378
|
+
\brief Starts enrollment operation.
|
379
|
+
|
380
|
+
\param fmd_type type of FMD to produce as a result of enrollment operation
|
381
|
+
\return DPFJ_SUCCESS: Enrollment started.
|
382
|
+
\return DPFJ_E_INVALID_PARAMETER: Requested FMD type is invalid.
|
383
|
+
\return DPFJ_E_ENROLLMENT_IN_PROGRESS: Another enrollment operation is in prgress.
|
384
|
+
\return DPFJ_E_FAILURE: Unknown error.
|
385
|
+
*/
|
386
|
+
int dpfj_start_enrollment(
|
387
|
+
DPFJ_FMD_FORMAT fmd_type
|
388
|
+
);
|
389
|
+
|
390
|
+
/**
|
391
|
+
\brief Adds FMD to enrollment operation.
|
392
|
+
|
393
|
+
Add an FMD to the pool of FMDs for enrollment and return a flag indicating when the enrollment is ready.
|
394
|
+
This function must be called before dpfj_create_enrollment_fmd.
|
395
|
+
|
396
|
+
\param fmd_type type of the FMD.
|
397
|
+
\param fmd pointer to the FMD data.
|
398
|
+
\param fmd_size size of the FMD data.
|
399
|
+
\param fmd_view_idx index of the view
|
400
|
+
\return DPFJ_SUCCESS: FMD added, enrollment is ready.
|
401
|
+
\return DPFJ_E_MORE_DATA: FMD added, more FMDs for enrollment required.
|
402
|
+
\return DPFJ_E_INVALID_PARAMETER: One or more parameters passed are invalid.
|
403
|
+
\return DPFJ_E_ENROLLMENT_NOT_STARTED: Enrollment is not started.
|
404
|
+
\return DPFJ_E_FAILURE: Unknown error.
|
405
|
+
*/
|
406
|
+
int dpfj_add_to_enrollment(
|
407
|
+
DPFJ_FMD_FORMAT fmd_type,
|
408
|
+
unsigned char* fmd,
|
409
|
+
unsigned int fmd_size,
|
410
|
+
unsigned int fmd_view_idx
|
411
|
+
);
|
412
|
+
|
413
|
+
/**
|
414
|
+
\brief Creates and returns enrollment FMD.
|
415
|
+
|
416
|
+
Create an FMD for an enrolled finger. The output FMD is suitable for storing in a database of enrolled users.
|
417
|
+
Some applications like voting, banking and law enforcement require that you check for duplicate fingerprints before storing a new fingerprint in the database.
|
418
|
+
For ANSI/ISO formats, the enrollment FMD is a standard FMD (the same as an FMD generated by the extraction function). For the DigitalPersona data format,
|
419
|
+
the enrollment FMD uses the "fingerprint template" format as used by legacy DigitalPersona applications.
|
420
|
+
This function must be called after dpfj_add_to_enrollment.
|
421
|
+
The size of the resulting FMD will vary depending on the minutiae in the fingerprint(s) that were enrolled. The maximum possible size of an FMD is MAX_FMD_SIZE.
|
422
|
+
If the value pointed to by fmd_size is zero, the function will return with the error code DPFJ_E_MORE_DATA and the required size will be stored in the value pointed to by fmd_size.
|
423
|
+
In order to determine the size, this function processes the image, extracts features and discards the FMD, so it takes significant processing time.
|
424
|
+
However if memory shortages are a key issue, this allows you to allocate memory more efficiently at the expense of processing time.
|
425
|
+
If memory is available, you will get the best performance if you always allocate MAX_FMD_SIZE for the FMD.
|
426
|
+
The value pointed to by fmd_size will always be returned as the actual size of the FMD that was extracted.
|
427
|
+
|
428
|
+
\param fmd pointer to recieve FMD data
|
429
|
+
\param fmd_size pointer to allocated size for the FMD data, pointer to receive the actual size of the FMD data
|
430
|
+
\return DPFJ_SUCCESS: FMD created.
|
431
|
+
\return DPFJ_E_MORE_DATA: FMD created, but allocated memory is not sufficient. The required memory size is in the fmd_size.
|
432
|
+
\return DPFJ_E_INVALID_PARAMETER: One or more parameters passed are invalid.
|
433
|
+
\return DPFJ_E_ENROLLMENT_NOT_STARTED: Enrollment is not started.
|
434
|
+
\return DPFJ_E_FAILURE: Unknown error.
|
435
|
+
*/
|
436
|
+
int dpfj_create_enrollment_fmd(
|
437
|
+
unsigned char* fmd,
|
438
|
+
unsigned int* fmd_size
|
439
|
+
);
|
440
|
+
|
441
|
+
/**
|
442
|
+
\brief Ends enrollment operation, releases memory.
|
443
|
+
|
444
|
+
This function releases resources used during the enrollment process. Call after enrollment is complete.
|
445
|
+
\return DPFJ_SUCCESS: Enrollment ended.
|
446
|
+
\return DPFJ_E_FAILURE: Unknown error.
|
447
|
+
*/
|
448
|
+
int dpfj_finish_enrollment();
|
449
|
+
|
450
|
+
/**
|
451
|
+
\brief Converts an FMD from any supported format to any other supported format.
|
452
|
+
|
453
|
+
\param fmd1_type type of the input FMD
|
454
|
+
\param fmd1 pointer to the input FMD data
|
455
|
+
\param fmd1_size size of the input FMD data
|
456
|
+
\param fmd2_type type of the target FMD
|
457
|
+
\param fmd2 pointer to receive target FMD data
|
458
|
+
\param fmd2_size pointer to allocated size for the FMD data, pointer to receive the actual size of the FMD data
|
459
|
+
\return DPFJ_SUCCESS: FMD was converted;
|
460
|
+
\return DPFJ_E_INVALID_PARAMETER: One or more parameters passed are invalid.
|
461
|
+
\return DPFJ_E_FAILURE: Failed to convert FMD.
|
462
|
+
*/
|
463
|
+
int dpfj_fmd_convert(
|
464
|
+
DPFJ_FMD_FORMAT fmd1_type,
|
465
|
+
unsigned char* fmd1,
|
466
|
+
unsigned int fmd1_size,
|
467
|
+
DPFJ_FMD_FORMAT fmd2_type,
|
468
|
+
unsigned char* fmd2,
|
469
|
+
unsigned int* fmd2_size
|
470
|
+
);
|
471
|
+
|
472
|
+
/****************************************************************************************************
|
473
|
+
legacy DigitalPersona image format conversion
|
474
|
+
****************************************************************************************************/
|
475
|
+
|
476
|
+
/**
|
477
|
+
\brief Converts legacy DigitalPersona image to the image in ANSI or ISO format.
|
478
|
+
|
479
|
+
\param dp_image pointer to the DP image data
|
480
|
+
\param dp_image_size size of the DP image data
|
481
|
+
\param fid_type type of the FID
|
482
|
+
\param fid_dpi resolution of the FID, valid values are 500 and 1000
|
483
|
+
\param rotate180 flag: rotate image, 0 - do not rotate, 1 - rotate
|
484
|
+
\param fid pointer to receive FID data
|
485
|
+
\param fid_size pointer to receive the size of the FID
|
486
|
+
\return DPFJ_SUCCESS: FID was created
|
487
|
+
\return DPFJ_E_FAILURE: Failed to create FID
|
488
|
+
*/
|
489
|
+
int dpfj_dp_fid_convert(
|
490
|
+
unsigned char* dp_image,
|
491
|
+
unsigned int dp_image_size,
|
492
|
+
DPFJ_FID_FORMAT fid_type,
|
493
|
+
unsigned int fid_dpi,
|
494
|
+
unsigned int rotate180,
|
495
|
+
unsigned char* fid,
|
496
|
+
unsigned int* fid_size
|
497
|
+
);
|
498
|
+
|
499
|
+
/****************************************************************************************************
|
500
|
+
FID and FMD manipulation: types and definitions
|
501
|
+
****************************************************************************************************/
|
502
|
+
|
503
|
+
#ifndef DPFJ_NO_IM_MANIPULATION
|
504
|
+
|
505
|
+
/**
|
506
|
+
\brief Define image properties.
|
507
|
+
|
508
|
+
Structure defines image properties for FIDs in ANSI 381-2004
|
509
|
+
and ISO 19794-4-2005 formats.
|
510
|
+
*/
|
511
|
+
typedef struct dpfj_fid_record_params{
|
512
|
+
unsigned int record_length; /**< total length of the image, including headers and all views */
|
513
|
+
unsigned int cbeff_id; /**< CBEFF product identifier */
|
514
|
+
unsigned int capture_device_id; /**< vendor specified */
|
515
|
+
unsigned int acquisition_level; /**< from Table 1 in "ANSI INSITS 381-2004" */
|
516
|
+
unsigned int finger_cnt; /**< total number of fingerprints in the record, must be greater or equal to 1 */
|
517
|
+
unsigned int scale_units; /**< pixels/cm (2) or pixels/inch (1) */
|
518
|
+
unsigned int scan_res; /**< scan resolution */
|
519
|
+
unsigned int image_res; /**< image resolution */
|
520
|
+
unsigned int bpp; /**< pixel depth, 1 - 16 bits */
|
521
|
+
unsigned int compression; /**< from Table 3 in "ANSI INSITS 381-2004" */
|
522
|
+
} DPFJ_FID_RECORD_PARAMS;
|
523
|
+
|
524
|
+
/**
|
525
|
+
\brief Define fingerprint image view (FIV) properties.
|
526
|
+
|
527
|
+
Structure defines image view properties for FIVs in ANSI 381-2004
|
528
|
+
and ISO 19794-4-2005 formats.
|
529
|
+
*/
|
530
|
+
typedef struct dpfj_fid_view_params{
|
531
|
+
unsigned int data_length; /**< total length of the finger data including headers and all views */
|
532
|
+
DPFJ_FINGER_POSITION finger_position; /**< finger position */
|
533
|
+
unsigned int view_cnt; /**< number of views associated with this finger, must be greater or equal to 1 */
|
534
|
+
unsigned int view_number; /**< 1 - 256 */
|
535
|
+
unsigned int quality; /**< 1 - 100 for ISO; 1 - 100, 254 for ANSI */
|
536
|
+
DPFJ_SCAN_TYPE impression_type; /**< impression type */
|
537
|
+
unsigned int width; /**< width of the fingerprint view, in pixels */
|
538
|
+
unsigned int height; /**< height of the fingerprint view, in pixels */
|
539
|
+
unsigned char* view_data; /**< pointer to the view data */
|
540
|
+
} DPFJ_FID_VIEW_PARAMS;
|
541
|
+
|
542
|
+
/**
|
543
|
+
\brief Define FMD properties.
|
544
|
+
|
545
|
+
Structure defines minutiae data properties for FMDs in ANSI 378-2004
|
546
|
+
and ISO 19794-2-2005 formats.
|
547
|
+
*/
|
548
|
+
typedef struct dpfj_fmd_record_params{
|
549
|
+
unsigned int record_length; /**< total length of the image, including headers and all views */
|
550
|
+
unsigned int cbeff_id; /**< CBEFF product identifier */
|
551
|
+
unsigned int capture_equipment_comp; /**< 4 bits: compliance; */
|
552
|
+
unsigned int capture_equipment_id; /**< 12 bits: capture device id, vendor specified */
|
553
|
+
unsigned int width; /**< width of the fingerprint image, in pixels */
|
554
|
+
unsigned int height; /**< height of the fingerprint image, in pixels */
|
555
|
+
unsigned int resolution; /**< resolution of the fingerprint image */
|
556
|
+
unsigned int view_cnt; /**< number of views */
|
557
|
+
} DPFJ_FMD_RECORD_PARAMS;
|
558
|
+
|
559
|
+
/**
|
560
|
+
\brief Define fingerprint minutiae view (FMV) properties.
|
561
|
+
|
562
|
+
Structure defines minutiae view properties for FMVs in ANSI 378-2004
|
563
|
+
and ISO 19794-2-2005 formats.
|
564
|
+
*/
|
565
|
+
typedef struct dpfj_fmd_view_params{
|
566
|
+
DPFJ_FINGER_POSITION finger_position; /**< 0 - 10, from Table 5 in "ANSI INSITS 381-2004" */
|
567
|
+
unsigned int view_number; /**< 0 - 15 */
|
568
|
+
DPFJ_SCAN_TYPE impression_type; /**< Table 2 in "ANSI INSITS 378-2004" */
|
569
|
+
unsigned int quality; /**< 1 - 100 */
|
570
|
+
unsigned int minutia_cnt; /**< number of minutiae */
|
571
|
+
unsigned int ext_block_length; /**< length of the extended data block, in bytes */
|
572
|
+
unsigned char* ext_block; /**< pointer to the extended data block */
|
573
|
+
} DPFJ_FMD_VIEW_PARAMS;
|
574
|
+
|
575
|
+
/****************************************************************************************************
|
576
|
+
FID manipulation
|
577
|
+
****************************************************************************************************/
|
578
|
+
|
579
|
+
/**
|
580
|
+
\brief Read image properties from FID.
|
581
|
+
|
582
|
+
\param image_type type of the FID (per DPFJ_FID_FORMAT)
|
583
|
+
\param image pointer to the FID
|
584
|
+
\param params pointer to the structure to receive image properties
|
585
|
+
\return void
|
586
|
+
*/
|
587
|
+
static inline void dpfj_get_fid_record_params(
|
588
|
+
DPFJ_FID_FORMAT image_type,
|
589
|
+
const unsigned char* image,
|
590
|
+
DPFJ_FID_RECORD_PARAMS* params
|
591
|
+
);
|
592
|
+
|
593
|
+
/**
|
594
|
+
\brief Writes image properties to FID.
|
595
|
+
|
596
|
+
\param params pointer to the structure containing image properties
|
597
|
+
\param image_type format of the FID (per DPFJ_FID_FORMAT)
|
598
|
+
\param image pointer to the FID
|
599
|
+
\return void
|
600
|
+
*/
|
601
|
+
static inline void dpfj_set_fid_record_params(
|
602
|
+
const DPFJ_FID_RECORD_PARAMS* params,
|
603
|
+
DPFJ_FID_FORMAT image_type,
|
604
|
+
unsigned char* image
|
605
|
+
);
|
606
|
+
|
607
|
+
/**
|
608
|
+
\brief Returns pointer to the specified view from FID.
|
609
|
+
|
610
|
+
\param image_type type of the FID (per DPFJ_FID_FORMAT)
|
611
|
+
\param image pointer to the FID
|
612
|
+
\param view_idx view index
|
613
|
+
\return offset to the specified view
|
614
|
+
*/
|
615
|
+
static inline unsigned int dpfj_get_fid_view_offset(
|
616
|
+
DPFJ_FID_FORMAT image_type,
|
617
|
+
const unsigned char* image,
|
618
|
+
const unsigned int view_idx
|
619
|
+
);
|
620
|
+
|
621
|
+
/**
|
622
|
+
\brief Read image view properties from FID.
|
623
|
+
|
624
|
+
\param view pointer to the view from the FID
|
625
|
+
\param params pointer to the structure to receive view properties
|
626
|
+
\return void
|
627
|
+
*/
|
628
|
+
static inline void dpfj_get_fid_view_params(
|
629
|
+
const unsigned char* view,
|
630
|
+
DPFJ_FID_VIEW_PARAMS* params
|
631
|
+
);
|
632
|
+
|
633
|
+
/**
|
634
|
+
\brief Write image view properties to FID.
|
635
|
+
|
636
|
+
\param params pointer to the structure containing view properties
|
637
|
+
\param view pointer to the view from the FID
|
638
|
+
\return void
|
639
|
+
*/
|
640
|
+
static inline void dpfj_set_fid_view_params(
|
641
|
+
const DPFJ_FID_VIEW_PARAMS* params,
|
642
|
+
unsigned char* view
|
643
|
+
);
|
644
|
+
|
645
|
+
/****************************************************************************************************
|
646
|
+
FMD manipulation
|
647
|
+
****************************************************************************************************/
|
648
|
+
|
649
|
+
/**
|
650
|
+
\brief Read minutiae record properties from FMD.
|
651
|
+
|
652
|
+
\param fmd_type format of the FMD (per DPFJ_FMD_FORMAT)
|
653
|
+
\param fmd pointer to the FMD
|
654
|
+
\param params pointer to the structure to receive FMD properties
|
655
|
+
\return void
|
656
|
+
*/
|
657
|
+
static inline void dpfj_get_fmd_record_params(
|
658
|
+
DPFJ_FMD_FORMAT fmd_type,
|
659
|
+
const unsigned char* fmd,
|
660
|
+
DPFJ_FMD_RECORD_PARAMS* params
|
661
|
+
);
|
662
|
+
|
663
|
+
/** \brief Write minutiae record properties to FMD.
|
664
|
+
|
665
|
+
\param params pointer to the structure containing FMD properties
|
666
|
+
\param fmd_type format of the FMD (per DPFJ_FMD_FORMAT)
|
667
|
+
\param fmd pointer to the FMD
|
668
|
+
\return void
|
669
|
+
*/
|
670
|
+
static inline void dpfj_set_fmd_record_params(
|
671
|
+
const DPFJ_FMD_RECORD_PARAMS* params,
|
672
|
+
DPFJ_FMD_FORMAT fmd_type,
|
673
|
+
unsigned char* fmd
|
674
|
+
);
|
675
|
+
|
676
|
+
/**
|
677
|
+
\brief Return pointer to the specified view from FMD.
|
678
|
+
|
679
|
+
\param fmd_type format of the FMD (per DPFJ_FMD_FORMAT)
|
680
|
+
\param fmd pointer to the FMD
|
681
|
+
\param view_idx view index
|
682
|
+
\return offset to the specified view
|
683
|
+
*/
|
684
|
+
static inline unsigned int dpfj_get_fmd_view_offset(
|
685
|
+
DPFJ_FMD_FORMAT fmd_type,
|
686
|
+
const unsigned char* fmd,
|
687
|
+
const unsigned int view_idx
|
688
|
+
);
|
689
|
+
|
690
|
+
/**
|
691
|
+
\brief Read view properties from FMD.
|
692
|
+
|
693
|
+
\param view pointer to the view from the FMD
|
694
|
+
\param params pointer to the structure to receive view properties
|
695
|
+
\return void
|
696
|
+
*/
|
697
|
+
static inline void dpfj_get_fmd_view_params(
|
698
|
+
const unsigned char* view,
|
699
|
+
DPFJ_FMD_VIEW_PARAMS* params
|
700
|
+
);
|
701
|
+
|
702
|
+
/**
|
703
|
+
\brief Write view properties to FMD.
|
704
|
+
|
705
|
+
\param params pointer to the structure containing view properties
|
706
|
+
\param view pointer to the view from the FMD
|
707
|
+
\return void
|
708
|
+
*/
|
709
|
+
static inline void dpfj_set_fmd_view_params(
|
710
|
+
const DPFJ_FMD_VIEW_PARAMS* params,
|
711
|
+
unsigned char* view
|
712
|
+
);
|
713
|
+
|
714
|
+
|
715
|
+
/****************************************************************************************************
|
716
|
+
FID and FMD manipulation: implementation
|
717
|
+
****************************************************************************************************/
|
718
|
+
|
719
|
+
/** \cond NEVER */
|
720
|
+
|
721
|
+
static inline unsigned int read_be16(const unsigned char* addr) {
|
722
|
+
unsigned int var = *addr;
|
723
|
+
var <<= 8;
|
724
|
+
var |= *(addr + 1);
|
725
|
+
return var;
|
726
|
+
};
|
727
|
+
|
728
|
+
static inline void write_be16(unsigned int var, unsigned char* addr) {
|
729
|
+
*(addr) = (unsigned char)(var >> 8);
|
730
|
+
*(addr + 1) = (unsigned char)var;
|
731
|
+
};
|
732
|
+
|
733
|
+
static inline unsigned int read_be32(const unsigned char* addr) {
|
734
|
+
unsigned int var = *(addr);
|
735
|
+
var <<= 8;
|
736
|
+
var |= *(addr + 1);
|
737
|
+
var <<= 8;
|
738
|
+
var |= *(addr + 2);
|
739
|
+
var <<= 8;
|
740
|
+
var |= *(addr + 3);
|
741
|
+
return var;
|
742
|
+
};
|
743
|
+
|
744
|
+
static inline void write_be32(unsigned int var, unsigned char* addr) {
|
745
|
+
*(addr) = (unsigned char)(var >> 24);
|
746
|
+
*(addr + 1) = (unsigned char)(var >> 16);
|
747
|
+
*(addr + 2) = (unsigned char)(var >> 8);
|
748
|
+
*(addr + 3) = (unsigned char)var;
|
749
|
+
};
|
750
|
+
|
751
|
+
/****************************************************************************************************/
|
752
|
+
/* FID functions */
|
753
|
+
|
754
|
+
static inline void dpfj_get_fid_record_params(DPFJ_FID_FORMAT image_type, const unsigned char* image, DPFJ_FID_RECORD_PARAMS* params){
|
755
|
+
if(NULL == image) return;
|
756
|
+
|
757
|
+
params->record_length = read_be32(image + 10);
|
758
|
+
int off = (DPFJ_FID_ANSI_381_2004 == image_type) ? DPFJ_FID_ANSI_381_2004_RECORD_HEADER_LENGTH - DPFJ_FID_ISO_19794_4_2005_RECORD_HEADER_LENGTH : 0;
|
759
|
+
params->cbeff_id = (DPFJ_FID_ANSI_381_2004 == image_type) ? read_be32(image + 14) : 0;
|
760
|
+
params->capture_device_id = read_be16(image + 14 + off);
|
761
|
+
params->acquisition_level = read_be16(image + 16 + off);
|
762
|
+
params->finger_cnt = *(image + 18 + off);
|
763
|
+
params->scale_units = *(image + 19 + off);
|
764
|
+
params->scan_res = read_be16(image + 20 + off);
|
765
|
+
params->image_res = read_be16(image + 24 + off);
|
766
|
+
params->bpp = *(image + 28 + off);
|
767
|
+
params->compression = *(image + 29 + off);
|
768
|
+
}
|
769
|
+
|
770
|
+
static inline void dpfj_set_fid_record_params(const DPFJ_FID_RECORD_PARAMS* params, DPFJ_FID_FORMAT image_type, unsigned char* image){
|
771
|
+
if(NULL == image) return;
|
772
|
+
|
773
|
+
image[0] = 'F'; image[1] = 'I'; image[2] = 'R'; image[3] = 0;
|
774
|
+
image[4] = '0'; image[5] = '1'; image[6] = '0'; image[7] = 0;
|
775
|
+
write_be16(0, image + 8);
|
776
|
+
write_be32(params->record_length, image + 10);
|
777
|
+
int off = (DPFJ_FID_ANSI_381_2004 == image_type) ? 4 : 0;
|
778
|
+
if(DPFJ_FID_ANSI_381_2004 == image_type) write_be32(params->cbeff_id, image + 14);
|
779
|
+
write_be16(params->capture_device_id, image + 14 + off);
|
780
|
+
write_be16(params->acquisition_level, image + 16 + off);
|
781
|
+
*(image + 18 + off) = (unsigned char)params->finger_cnt;
|
782
|
+
*(image + 19 + off) = (unsigned char)params->scale_units;
|
783
|
+
write_be16(params->scan_res, image + 20 + off);
|
784
|
+
write_be16(params->scan_res, image + 22 + off);
|
785
|
+
write_be16(params->image_res, image + 24 + off);
|
786
|
+
write_be16(params->image_res, image + 26 + off);
|
787
|
+
*(image + 28 + off) = (unsigned char)params->bpp;
|
788
|
+
*(image + 29 + off) = (unsigned char)params->compression;
|
789
|
+
write_be16(0, image + 30 + off);
|
790
|
+
}
|
791
|
+
|
792
|
+
static inline unsigned int dpfj_get_fid_view_offset(DPFJ_FID_FORMAT image_type, const unsigned char* image, unsigned int view_idx){
|
793
|
+
if(NULL == image) return 0;
|
794
|
+
|
795
|
+
unsigned int record_length = read_be32(image + 10);
|
796
|
+
unsigned int pos = (DPFJ_FID_ANSI_381_2004 == image_type) ? DPFJ_FID_ANSI_381_2004_RECORD_HEADER_LENGTH : DPFJ_FID_ISO_19794_4_2005_RECORD_HEADER_LENGTH;
|
797
|
+
unsigned int i = 0;
|
798
|
+
for(i = 0; i < view_idx && pos < record_length; i++){
|
799
|
+
//go to next
|
800
|
+
pos += read_be32(image + pos);
|
801
|
+
}
|
802
|
+
|
803
|
+
//check if offset is valid
|
804
|
+
if(pos >= record_length) return 0;
|
805
|
+
return pos;
|
806
|
+
}
|
807
|
+
|
808
|
+
static inline void dpfj_get_fid_view_params(const unsigned char* view, DPFJ_FID_VIEW_PARAMS* params){
|
809
|
+
if(NULL == view) return;
|
810
|
+
|
811
|
+
params->data_length = read_be32(view);
|
812
|
+
params->finger_position = (DPFJ_FINGER_POSITION)*(view + 4);
|
813
|
+
params->view_cnt = (unsigned int)*(view + 5);
|
814
|
+
params->view_number = (unsigned int)*(view + 6);
|
815
|
+
params->quality = (unsigned int)*(view + 7);
|
816
|
+
params->impression_type = (DPFJ_SCAN_TYPE)*(view + 8);
|
817
|
+
params->width = read_be16(view + 9);
|
818
|
+
params->height = read_be16(view + 11);
|
819
|
+
params->view_data = (unsigned char*)(view + DPFJ_FID_ANSI_ISO_VIEW_HEADER_LENGTH);
|
820
|
+
}
|
821
|
+
|
822
|
+
static inline void dpfj_set_fid_view_params(const DPFJ_FID_VIEW_PARAMS* params, unsigned char* view){
|
823
|
+
if(NULL == view) return;
|
824
|
+
|
825
|
+
unsigned int view_size = params->width * params->height + DPFJ_FID_ANSI_ISO_VIEW_HEADER_LENGTH;
|
826
|
+
write_be32(view_size, view);
|
827
|
+
*(view + 4) = (unsigned char)params->finger_position;
|
828
|
+
*(view + 5) = (unsigned char)params->view_cnt;
|
829
|
+
*(view + 6) = (unsigned char)params->view_number;
|
830
|
+
*(view + 7) = (unsigned char)params->quality;
|
831
|
+
*(view + 8) = (unsigned char)params->impression_type;
|
832
|
+
write_be16(params->width, view + 9);
|
833
|
+
write_be16(params->height, view + 11);
|
834
|
+
*(view + 13) = 0;
|
835
|
+
}
|
836
|
+
|
837
|
+
/****************************************************************************************************/
|
838
|
+
/* FMD functions */
|
839
|
+
|
840
|
+
static inline void dpfj_get_fmd_record_params(DPFJ_FMD_FORMAT fmd_type, const unsigned char* fmd, DPFJ_FMD_RECORD_PARAMS* params){
|
841
|
+
if(NULL == fmd) return;
|
842
|
+
|
843
|
+
int off = 0;
|
844
|
+
if(DPFJ_FMD_ANSI_378_2004 == fmd_type){
|
845
|
+
params->record_length = read_be16(fmd + 8);
|
846
|
+
params->cbeff_id = read_be32(fmd + 10);
|
847
|
+
off = 2;
|
848
|
+
if(0 == params->record_length){
|
849
|
+
params->record_length = read_be32(fmd + 10);
|
850
|
+
params->cbeff_id = read_be32(fmd + 14);
|
851
|
+
off = 6;
|
852
|
+
}
|
853
|
+
}
|
854
|
+
else if(DPFJ_FMD_ISO_19794_2_2005 == fmd_type){
|
855
|
+
params->record_length = read_be32(fmd + 8);
|
856
|
+
params->cbeff_id = 0;
|
857
|
+
}
|
858
|
+
else return;
|
859
|
+
|
860
|
+
params->capture_equipment_comp = *(fmd + 12 + off) & 0xf0;
|
861
|
+
params->capture_equipment_id = read_be16(fmd + 12 + off) & 0x0fff;
|
862
|
+
params->width = read_be16(fmd + 14 + off);
|
863
|
+
params->height = read_be16(fmd + 16 + off);
|
864
|
+
params->resolution = read_be16(fmd + 18 + off);
|
865
|
+
params->view_cnt = *(fmd + 22 + off);
|
866
|
+
}
|
867
|
+
|
868
|
+
static inline void dpfj_set_fmd_record_params(const DPFJ_FMD_RECORD_PARAMS* params, DPFJ_FMD_FORMAT fmd_type, unsigned char* fmd){
|
869
|
+
if(NULL == fmd) return;
|
870
|
+
|
871
|
+
fmd[0] = 'F'; fmd[1] = 'M'; fmd[2] = 'R'; fmd[3] = 0;
|
872
|
+
fmd[4] = ' '; fmd[5] = '2'; fmd[6] = '0'; fmd[7] = 0;
|
873
|
+
|
874
|
+
int off = 0;
|
875
|
+
if(DPFJ_FMD_ANSI_378_2004 == fmd_type){
|
876
|
+
if(0xffff < params->record_length){
|
877
|
+
off = 6;
|
878
|
+
write_be32(params->record_length, fmd + 10);
|
879
|
+
write_be32(params->cbeff_id, fmd + 14);
|
880
|
+
}
|
881
|
+
else{
|
882
|
+
off = 2;
|
883
|
+
write_be16(params->record_length, fmd + 8);
|
884
|
+
write_be32(params->cbeff_id, fmd + 10);
|
885
|
+
}
|
886
|
+
}
|
887
|
+
else if(DPFJ_FMD_ISO_19794_2_2005 == fmd_type){
|
888
|
+
write_be32(params->record_length, fmd + 8);
|
889
|
+
}
|
890
|
+
else return;
|
891
|
+
|
892
|
+
*(fmd + 12 + off) = (unsigned char)(((params->capture_equipment_comp & 0x0f) << 4) || ((params->capture_equipment_id >> 16) & 0x0f));
|
893
|
+
*(fmd + 13 + off) = (unsigned char)(params->capture_equipment_id & 0xff);
|
894
|
+
write_be16(params->width, fmd + 14 + off);
|
895
|
+
write_be16(params->height, fmd + 16 + off);
|
896
|
+
write_be16(params->resolution, fmd + 18 + off);
|
897
|
+
write_be16(params->resolution, fmd + 20 + off);
|
898
|
+
*(fmd + 22 + off) = (unsigned char)params->view_cnt;
|
899
|
+
*(fmd + 23 + off) = 0;
|
900
|
+
}
|
901
|
+
|
902
|
+
static inline unsigned int dpfj_get_fmd_view_offset(DPFJ_FMD_FORMAT fmd_type, const unsigned char* fmd, unsigned int view_idx){
|
903
|
+
if(NULL == fmd) return 0;
|
904
|
+
|
905
|
+
DPFJ_FMD_RECORD_PARAMS rp = {0};
|
906
|
+
dpfj_get_fmd_record_params(fmd_type, fmd, &rp);
|
907
|
+
|
908
|
+
//check index
|
909
|
+
if(view_idx >= rp.view_cnt) return 0; //invalid view index
|
910
|
+
|
911
|
+
unsigned int pos = DPFJ_FMD_ISO_19794_2_2005_RECORD_HEADER_LENGTH;
|
912
|
+
if(DPFJ_FMD_ANSI_378_2004 == fmd_type){
|
913
|
+
pos = DPFJ_FMD_ANSI_378_2004_RECORD_HEADER_LENGTH;
|
914
|
+
if(0xffff < rp.record_length) pos += 4;
|
915
|
+
}
|
916
|
+
unsigned int i = 0;
|
917
|
+
for(i = 0; i < view_idx && pos < rp.record_length; i++){
|
918
|
+
pos += (unsigned int)*(fmd + pos + 3) * DPFJ_FMD_ANSI_ISO_MINITIA_LENGTH + DPFJ_FMD_ANSI_ISO_VIEW_HEADER_LENGTH;
|
919
|
+
pos += read_be16(fmd + pos) + 2;
|
920
|
+
}
|
921
|
+
|
922
|
+
//check if offset is valid
|
923
|
+
if(pos >= rp.record_length) return 0;
|
924
|
+
return pos;
|
925
|
+
}
|
926
|
+
|
927
|
+
static inline void dpfj_get_fmd_view_params(const unsigned char* view, DPFJ_FMD_VIEW_PARAMS* params){
|
928
|
+
if(NULL == view) return;
|
929
|
+
|
930
|
+
params->finger_position = (DPFJ_FINGER_POSITION)*view;
|
931
|
+
params->view_number = (unsigned int)(*(view + 1) >> 4) & 0x0f;
|
932
|
+
params->impression_type = (DPFJ_SCAN_TYPE)(*(view + 1) & 0x0f);
|
933
|
+
params->quality = (unsigned int)*(view + 2);
|
934
|
+
params->minutia_cnt = (unsigned int)*(view + 3);
|
935
|
+
params->ext_block_length = read_be16(view + 4 + params->minutia_cnt * DPFJ_FMD_ANSI_ISO_MINITIA_LENGTH);
|
936
|
+
params->ext_block = (unsigned char*)(view + 4 + params->minutia_cnt * DPFJ_FMD_ANSI_ISO_MINITIA_LENGTH + 2);
|
937
|
+
}
|
938
|
+
|
939
|
+
static inline void dpfj_set_fmd_view_params(const DPFJ_FMD_VIEW_PARAMS* params, unsigned char* view){
|
940
|
+
if(NULL == view) return;
|
941
|
+
|
942
|
+
*view = (unsigned char)params->finger_position;
|
943
|
+
*(view + 1) = (unsigned char)((params->view_number << 4) | (params->impression_type & 0x0f));
|
944
|
+
*(view + 2) = (unsigned char)params->quality;
|
945
|
+
*(view + 3) = (unsigned char)params->minutia_cnt;
|
946
|
+
unsigned char* ext_block = view + 4 + params->minutia_cnt * DPFJ_FMD_ANSI_ISO_MINITIA_LENGTH;
|
947
|
+
write_be16(params->ext_block_length, ext_block);
|
948
|
+
ext_block += 2;
|
949
|
+
if(ext_block != params->ext_block){
|
950
|
+
unsigned int i = 0;
|
951
|
+
for(i = 0; i < params->ext_block_length; i++) ext_block[i] = params->ext_block[i];
|
952
|
+
}
|
953
|
+
}
|
954
|
+
|
955
|
+
/** \endcond */
|
956
|
+
|
957
|
+
#endif /* DPFJ_NO_IM_MANIPULATION */
|
958
|
+
|
959
|
+
#ifdef __cplusplus
|
960
|
+
}
|
961
|
+
#endif /* __cplusplus */
|
962
|
+
|
963
|
+
#endif /* __DPFJ_H__ */
|