fingerprint-ruby 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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__ */
|