matchpat.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. /*******************************************************************************
  2. License:
  3. This software and/or related materials was developed at the National Institute
  4. of Standards and Technology (NIST) by employees of the Federal Government
  5. in the course of their official duties. Pursuant to title 17 Section 105
  6. of the United States Code, this software is not subject to copyright
  7. protection and is in the public domain.
  8. This software and/or related materials have been determined to be not subject
  9. to the EAR (see Part 734.3 of the EAR for exact details) because it is
  10. a publicly available technology and software, and is freely distributed
  11. to any interested party with no licensing requirements. Therefore, it is
  12. permissible to distribute this software as a free download from the internet.
  13. Disclaimer:
  14. This software and/or related materials was developed to promote biometric
  15. standards and biometric technology testing for the Federal Government
  16. in accordance with the USA PATRIOT Act and the Enhanced Border Security
  17. and Visa Entry Reform Act. Specific hardware and software products identified
  18. in this software were used in order to perform the software development.
  19. In no case does such identification imply recommendation or endorsement
  20. by the National Institute of Standards and Technology, nor does it imply that
  21. the products and equipment identified are necessarily the best available
  22. for the purpose.
  23. This software and/or related materials are provided "AS-IS" without warranty
  24. of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
  25. NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
  26. or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
  27. licensed product, however used. In no event shall NIST be liable for any
  28. damages and/or costs, including but not limited to incidental or consequential
  29. damages of any kind, including economic damage or injury to property and lost
  30. profits, regardless of whether NIST shall be advised, have reason to know,
  31. or in fact shall know of the possibility.
  32. By using this software, you agree to bear all risk relating to quality,
  33. use and performance of the software and/or related materials. You agree
  34. to hold the Government harmless from any claim arising from your use
  35. of the software.
  36. *******************************************************************************/
  37. /***********************************************************************
  38. LIBRARY: LFS - NIST Latent Fingerprint System
  39. FILE: MATCHPAT.C
  40. AUTHOR: Michael D. Garris
  41. DATE: 05/11/1999
  42. UPDATED: 03/16/2005 by MDG
  43. Contains routines responsible for matching minutia feature
  44. patterns as part of the NIST Latent Fingerprint System (LFS).
  45. ***********************************************************************
  46. ROUTINES:
  47. match_1st_pair()
  48. match_2nd_pair()
  49. match_3rd_pair()
  50. skip_repeated_horizontal_pair()
  51. skip_repeated_vertical_pair()
  52. ***********************************************************************/
  53. #include <stdio.h>
  54. #include "lfs.h"
  55. /*************************************************************************
  56. **************************************************************************
  57. #cat: match_1st_pair - Determines which of the feature_patterns[] have their
  58. #cat: first pixel pair match the specified pixel pair.
  59. Input:
  60. p1 - first pixel value of pair
  61. p2 - second pixel value of pair
  62. Output:
  63. possible - list of matching feature_patterns[] indices
  64. nposs - number of matches
  65. Return Code:
  66. nposs - number of matches
  67. *************************************************************************/
  68. int match_1st_pair(unsigned char p1, unsigned char p2,
  69. int *possible, int *nposs)
  70. {
  71. int i;
  72. /* Set possibilities to 0 */
  73. *nposs = 0;
  74. /* Foreach set of feature pairs ... */
  75. for(i = 0; i < NFEATURES; i++){
  76. /* If current scan pair matches first pair for feature ... */
  77. if((p1==feature_patterns[i].first[0]) &&
  78. (p2==feature_patterns[i].first[1])){
  79. /* Store feature as a possible match. */
  80. possible[*nposs] = i;
  81. /* Bump number of stored possibilities. */
  82. (*nposs)++;
  83. }
  84. }
  85. /* Return number of stored possibilities. */
  86. return(*nposs);
  87. }
  88. /*************************************************************************
  89. **************************************************************************
  90. #cat: match_2nd_pair - Determines which of the passed feature_patterns[] have
  91. #cat: their second pixel pair match the specified pixel pair.
  92. Input:
  93. p1 - first pixel value of pair
  94. p2 - second pixel value of pair
  95. possible - list of potentially-matching feature_patterns[] indices
  96. nposs - number of potential matches
  97. Output:
  98. possible - list of matching feature_patterns[] indices
  99. nposs - number of matches
  100. Return Code:
  101. nposs - number of matches
  102. *************************************************************************/
  103. int match_2nd_pair(unsigned char p1, unsigned char p2,
  104. int *possible, int *nposs)
  105. {
  106. int i;
  107. int tnposs;
  108. /* Store input possibilities. */
  109. tnposs = *nposs;
  110. /* Reset output possibilities to 0. */
  111. *nposs = 0;
  112. /* If current scan pair values are the same ... */
  113. if(p1 == p2)
  114. /* Simply return because pair can't be a second feature pair. */
  115. return(*nposs);
  116. /* Foreach possible match based on first pair ... */
  117. for(i = 0; i < tnposs; i++){
  118. /* If current scan pair matches second pair for feature ... */
  119. if((p1==feature_patterns[possible[i]].second[0]) &&
  120. (p2==feature_patterns[possible[i]].second[1])){
  121. /* Store feature as a possible match. */
  122. possible[*nposs] = possible[i];
  123. /* Bump number of stored possibilities. */
  124. (*nposs)++;
  125. }
  126. }
  127. /* Return number of stored possibilities. */
  128. return(*nposs);
  129. }
  130. /*************************************************************************
  131. **************************************************************************
  132. #cat: match_3rd_pair - Determines which of the passed feature_patterns[] have
  133. #cat: their third pixel pair match the specified pixel pair.
  134. Input:
  135. p1 - first pixel value of pair
  136. p2 - second pixel value of pair
  137. possible - list of potentially-matching feature_patterns[] indices
  138. nposs - number of potential matches
  139. Output:
  140. possible - list of matching feature_patterns[] indices
  141. nposs - number of matches
  142. Return Code:
  143. nposs - number of matches
  144. *************************************************************************/
  145. int match_3rd_pair(unsigned char p1, unsigned char p2,
  146. int *possible, int *nposs)
  147. {
  148. int i;
  149. int tnposs;
  150. /* Store input possibilities. */
  151. tnposs = *nposs;
  152. /* Reset output possibilities to 0. */
  153. *nposs = 0;
  154. /* Foreach possible match based on first and second pairs ... */
  155. for(i = 0; i < tnposs; i++){
  156. /* If current scan pair matches third pair for feature ... */
  157. if((p1==feature_patterns[possible[i]].third[0]) &&
  158. (p2==feature_patterns[possible[i]].third[1])){
  159. /* Store feature as a possible match. */
  160. possible[*nposs] = possible[i];
  161. /* Bump number of stored possibilities. */
  162. (*nposs)++;
  163. }
  164. }
  165. /* Return number of stored possibilities. */
  166. return(*nposs);
  167. }
  168. /*************************************************************************
  169. **************************************************************************
  170. #cat: skip_repeated_horizontal_pair - Takes the location of two pixel in
  171. #cat: adjacent pixel rows within an image region and skips
  172. #cat: rightward until the either the pixel pair no longer repeats
  173. #cat: itself or the image region is exhausted.
  174. Input:
  175. cx - current x-coord of starting pixel pair
  176. ex - right edge of the image region
  177. p1ptr - pointer to current top pixel in pair
  178. p2ptr - pointer to current bottom pixel in pair
  179. iw - width (in pixels) of image
  180. ih - height (in pixels) of image
  181. Output:
  182. cx - x-coord of where rightward skip terminated
  183. p1ptr - points to top pixel where rightward skip terminated
  184. p2ptr - points to bottom pixel where rightward skip terminated
  185. *************************************************************************/
  186. void skip_repeated_horizontal_pair(int *cx, const int ex,
  187. unsigned char **p1ptr, unsigned char **p2ptr,
  188. const int iw, const int ih)
  189. {
  190. int old1, old2;
  191. /* Store starting pixel pair. */
  192. old1 = **p1ptr;
  193. old2 = **p2ptr;
  194. /* Bump horizontally to next pixel pair. */
  195. (*cx)++;
  196. (*p1ptr)++;
  197. (*p2ptr)++;
  198. /* While not at right of scan region... */
  199. while(*cx < ex){
  200. /* If one or the other pixels in the new pair are different */
  201. /* from the starting pixel pair... */
  202. if((**p1ptr != old1) || (**p2ptr != old2))
  203. /* Done skipping repreated pixel pairs. */
  204. return;
  205. /* Otherwise, bump horizontally to next pixel pair. */
  206. (*cx)++;
  207. (*p1ptr)++;
  208. (*p2ptr)++;
  209. }
  210. }
  211. /*************************************************************************
  212. **************************************************************************
  213. #cat: skip_repeated_vertical_pair - Takes the location of two pixel in
  214. #cat: adjacent pixel columns within an image region and skips
  215. #cat: downward until the either the pixel pair no longer repeats
  216. #cat: itself or the image region is exhausted.
  217. Input:
  218. cy - current y-coord of starting pixel pair
  219. ey - bottom of the image region
  220. p1ptr - pointer to current left pixel in pair
  221. p2ptr - pointer to current right pixel in pair
  222. iw - width (in pixels) of image
  223. ih - height (in pixels) of image
  224. Output:
  225. cy - y-coord of where downward skip terminated
  226. p1ptr - points to left pixel where downward skip terminated
  227. p2ptr - points to right pixel where donward skip terminated
  228. *************************************************************************/
  229. void skip_repeated_vertical_pair(int *cy, const int ey,
  230. unsigned char **p1ptr, unsigned char **p2ptr,
  231. const int iw, const int ih)
  232. {
  233. int old1, old2;
  234. /* Store starting pixel pair. */
  235. old1 = **p1ptr;
  236. old2 = **p2ptr;
  237. /* Bump vertically to next pixel pair. */
  238. (*cy)++;
  239. (*p1ptr)+=iw;
  240. (*p2ptr)+=iw;
  241. /* While not at bottom of scan region... */
  242. while(*cy < ey){
  243. /* If one or the other pixels in the new pair are different */
  244. /* from the starting pixel pair... */
  245. if((**p1ptr != old1) || (**p2ptr != old2))
  246. /* Done skipping repreated pixel pairs. */
  247. return;
  248. /* Otherwise, bump vertically to next pixel pair. */
  249. (*cy)++;
  250. (*p1ptr)+=iw;
  251. (*p2ptr)+=iw;
  252. }
  253. }