9fb789dc78
This updates NBIS to its latest 5.0.0 version, dated 04/03/2015, from a 1.x version, dated 2007. Original sources are available at: https://www.nist.gov/itl/iad/image-group/products-and-services/image-group-open-source-server-nigos#Releases And full change log at: https://www.nist.gov/sites/default/files/documents/2016/12/14/changelog.txt
292 lines
11 KiB
C
292 lines
11 KiB
C
/*******************************************************************************
|
|
|
|
License:
|
|
This software and/or related materials was developed at the National Institute
|
|
of Standards and Technology (NIST) by employees of the Federal Government
|
|
in the course of their official duties. Pursuant to title 17 Section 105
|
|
of the United States Code, this software is not subject to copyright
|
|
protection and is in the public domain.
|
|
|
|
This software and/or related materials have been determined to be not subject
|
|
to the EAR (see Part 734.3 of the EAR for exact details) because it is
|
|
a publicly available technology and software, and is freely distributed
|
|
to any interested party with no licensing requirements. Therefore, it is
|
|
permissible to distribute this software as a free download from the internet.
|
|
|
|
Disclaimer:
|
|
This software and/or related materials was developed to promote biometric
|
|
standards and biometric technology testing for the Federal Government
|
|
in accordance with the USA PATRIOT Act and the Enhanced Border Security
|
|
and Visa Entry Reform Act. Specific hardware and software products identified
|
|
in this software were used in order to perform the software development.
|
|
In no case does such identification imply recommendation or endorsement
|
|
by the National Institute of Standards and Technology, nor does it imply that
|
|
the products and equipment identified are necessarily the best available
|
|
for the purpose.
|
|
|
|
This software and/or related materials are provided "AS-IS" without warranty
|
|
of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
|
|
NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
|
|
or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
|
|
licensed product, however used. In no event shall NIST be liable for any
|
|
damages and/or costs, including but not limited to incidental or consequential
|
|
damages of any kind, including economic damage or injury to property and lost
|
|
profits, regardless of whether NIST shall be advised, have reason to know,
|
|
or in fact shall know of the possibility.
|
|
|
|
By using this software, you agree to bear all risk relating to quality,
|
|
use and performance of the software and/or related materials. You agree
|
|
to hold the Government harmless from any claim arising from your use
|
|
of the software.
|
|
|
|
*******************************************************************************/
|
|
|
|
|
|
/***********************************************************************
|
|
LIBRARY: LFS - NIST Latent Fingerprint System
|
|
|
|
FILE: MATCHPAT.C
|
|
AUTHOR: Michael D. Garris
|
|
DATE: 05/11/1999
|
|
UPDATED: 03/16/2005 by MDG
|
|
|
|
Contains routines responsible for matching minutia feature
|
|
patterns as part of the NIST Latent Fingerprint System (LFS).
|
|
|
|
***********************************************************************
|
|
ROUTINES:
|
|
match_1st_pair()
|
|
match_2nd_pair()
|
|
match_3rd_pair()
|
|
skip_repeated_horizontal_pair()
|
|
skip_repeated_vertical_pair()
|
|
***********************************************************************/
|
|
|
|
#include <stdio.h>
|
|
#include <lfs.h>
|
|
|
|
/*************************************************************************
|
|
**************************************************************************
|
|
#cat: match_1st_pair - Determines which of the g_feature_patterns[] have their
|
|
#cat: first pixel pair match the specified pixel pair.
|
|
|
|
Input:
|
|
p1 - first pixel value of pair
|
|
p2 - second pixel value of pair
|
|
Output:
|
|
possible - list of matching g_feature_patterns[] indices
|
|
nposs - number of matches
|
|
Return Code:
|
|
nposs - number of matches
|
|
*************************************************************************/
|
|
int match_1st_pair(unsigned char p1, unsigned char p2,
|
|
int *possible, int *nposs)
|
|
{
|
|
int i;
|
|
|
|
/* Set possibilities to 0 */
|
|
*nposs = 0;
|
|
|
|
/* Foreach set of feature pairs ... */
|
|
for(i = 0; i < NFEATURES; i++){
|
|
/* If current scan pair matches first pair for feature ... */
|
|
if((p1==g_feature_patterns[i].first[0]) &&
|
|
(p2==g_feature_patterns[i].first[1])){
|
|
/* Store feature as a possible match. */
|
|
possible[*nposs] = i;
|
|
/* Bump number of stored possibilities. */
|
|
(*nposs)++;
|
|
}
|
|
}
|
|
|
|
/* Return number of stored possibilities. */
|
|
return(*nposs);
|
|
}
|
|
|
|
/*************************************************************************
|
|
**************************************************************************
|
|
#cat: match_2nd_pair - Determines which of the passed g_feature_patterns[] have
|
|
#cat: their second pixel pair match the specified pixel pair.
|
|
|
|
Input:
|
|
p1 - first pixel value of pair
|
|
p2 - second pixel value of pair
|
|
possible - list of potentially-matching g_feature_patterns[] indices
|
|
nposs - number of potential matches
|
|
Output:
|
|
possible - list of matching g_feature_patterns[] indices
|
|
nposs - number of matches
|
|
Return Code:
|
|
nposs - number of matches
|
|
*************************************************************************/
|
|
int match_2nd_pair(unsigned char p1, unsigned char p2,
|
|
int *possible, int *nposs)
|
|
{
|
|
int i;
|
|
int tnposs;
|
|
|
|
/* Store input possibilities. */
|
|
tnposs = *nposs;
|
|
/* Reset output possibilities to 0. */
|
|
*nposs = 0;
|
|
|
|
/* If current scan pair values are the same ... */
|
|
if(p1 == p2)
|
|
/* Simply return because pair can't be a second feature pair. */
|
|
return(*nposs);
|
|
|
|
/* Foreach possible match based on first pair ... */
|
|
for(i = 0; i < tnposs; i++){
|
|
/* If current scan pair matches second pair for feature ... */
|
|
if((p1==g_feature_patterns[possible[i]].second[0]) &&
|
|
(p2==g_feature_patterns[possible[i]].second[1])){
|
|
/* Store feature as a possible match. */
|
|
possible[*nposs] = possible[i];
|
|
/* Bump number of stored possibilities. */
|
|
(*nposs)++;
|
|
}
|
|
}
|
|
|
|
/* Return number of stored possibilities. */
|
|
return(*nposs);
|
|
}
|
|
|
|
/*************************************************************************
|
|
**************************************************************************
|
|
#cat: match_3rd_pair - Determines which of the passed g_feature_patterns[] have
|
|
#cat: their third pixel pair match the specified pixel pair.
|
|
|
|
Input:
|
|
p1 - first pixel value of pair
|
|
p2 - second pixel value of pair
|
|
possible - list of potentially-matching g_feature_patterns[] indices
|
|
nposs - number of potential matches
|
|
Output:
|
|
possible - list of matching g_feature_patterns[] indices
|
|
nposs - number of matches
|
|
Return Code:
|
|
nposs - number of matches
|
|
*************************************************************************/
|
|
int match_3rd_pair(unsigned char p1, unsigned char p2,
|
|
int *possible, int *nposs)
|
|
{
|
|
int i;
|
|
int tnposs;
|
|
|
|
/* Store input possibilities. */
|
|
tnposs = *nposs;
|
|
/* Reset output possibilities to 0. */
|
|
*nposs = 0;
|
|
|
|
/* Foreach possible match based on first and second pairs ... */
|
|
for(i = 0; i < tnposs; i++){
|
|
/* If current scan pair matches third pair for feature ... */
|
|
if((p1==g_feature_patterns[possible[i]].third[0]) &&
|
|
(p2==g_feature_patterns[possible[i]].third[1])){
|
|
/* Store feature as a possible match. */
|
|
possible[*nposs] = possible[i];
|
|
/* Bump number of stored possibilities. */
|
|
(*nposs)++;
|
|
}
|
|
}
|
|
|
|
/* Return number of stored possibilities. */
|
|
return(*nposs);
|
|
}
|
|
|
|
/*************************************************************************
|
|
**************************************************************************
|
|
#cat: skip_repeated_horizontal_pair - Takes the location of two pixel in
|
|
#cat: adjacent pixel rows within an image region and skips
|
|
#cat: rightward until the either the pixel pair no longer repeats
|
|
#cat: itself or the image region is exhausted.
|
|
|
|
Input:
|
|
cx - current x-coord of starting pixel pair
|
|
ex - right edge of the image region
|
|
p1ptr - pointer to current top pixel in pair
|
|
p2ptr - pointer to current bottom pixel in pair
|
|
iw - width (in pixels) of image
|
|
ih - height (in pixels) of image
|
|
Output:
|
|
cx - x-coord of where rightward skip terminated
|
|
p1ptr - points to top pixel where rightward skip terminated
|
|
p2ptr - points to bottom pixel where rightward skip terminated
|
|
*************************************************************************/
|
|
void skip_repeated_horizontal_pair(int *cx, const int ex,
|
|
unsigned char **p1ptr, unsigned char **p2ptr,
|
|
const int iw, const int ih)
|
|
{
|
|
int old1, old2;
|
|
|
|
/* Store starting pixel pair. */
|
|
old1 = **p1ptr;
|
|
old2 = **p2ptr;
|
|
|
|
/* Bump horizontally to next pixel pair. */
|
|
(*cx)++;
|
|
(*p1ptr)++;
|
|
(*p2ptr)++;
|
|
|
|
/* While not at right of scan region... */
|
|
while(*cx < ex){
|
|
/* If one or the other pixels in the new pair are different */
|
|
/* from the starting pixel pair... */
|
|
if((**p1ptr != old1) || (**p2ptr != old2))
|
|
/* Done skipping repreated pixel pairs. */
|
|
return;
|
|
/* Otherwise, bump horizontally to next pixel pair. */
|
|
(*cx)++;
|
|
(*p1ptr)++;
|
|
(*p2ptr)++;
|
|
}
|
|
}
|
|
|
|
/*************************************************************************
|
|
**************************************************************************
|
|
#cat: skip_repeated_vertical_pair - Takes the location of two pixel in
|
|
#cat: adjacent pixel columns within an image region and skips
|
|
#cat: downward until the either the pixel pair no longer repeats
|
|
#cat: itself or the image region is exhausted.
|
|
|
|
Input:
|
|
cy - current y-coord of starting pixel pair
|
|
ey - bottom of the image region
|
|
p1ptr - pointer to current left pixel in pair
|
|
p2ptr - pointer to current right pixel in pair
|
|
iw - width (in pixels) of image
|
|
ih - height (in pixels) of image
|
|
Output:
|
|
cy - y-coord of where downward skip terminated
|
|
p1ptr - points to left pixel where downward skip terminated
|
|
p2ptr - points to right pixel where donward skip terminated
|
|
*************************************************************************/
|
|
void skip_repeated_vertical_pair(int *cy, const int ey,
|
|
unsigned char **p1ptr, unsigned char **p2ptr,
|
|
const int iw, const int ih)
|
|
{
|
|
int old1, old2;
|
|
|
|
/* Store starting pixel pair. */
|
|
old1 = **p1ptr;
|
|
old2 = **p2ptr;
|
|
|
|
/* Bump vertically to next pixel pair. */
|
|
(*cy)++;
|
|
(*p1ptr)+=iw;
|
|
(*p2ptr)+=iw;
|
|
|
|
/* While not at bottom of scan region... */
|
|
while(*cy < ey){
|
|
/* If one or the other pixels in the new pair are different */
|
|
/* from the starting pixel pair... */
|
|
if((**p1ptr != old1) || (**p2ptr != old2))
|
|
/* Done skipping repreated pixel pairs. */
|
|
return;
|
|
/* Otherwise, bump vertically to next pixel pair. */
|
|
(*cy)++;
|
|
(*p1ptr)+=iw;
|
|
(*p2ptr)+=iw;
|
|
}
|
|
}
|
|
|