GCC Code Coverage Report


Directory: ./
File: libfprint/nbis/mindtct/chaincod.c
Date: 2024-05-04 14:54:39
Exec Total Coverage
Lines: 32 36 88.9%
Functions: 2 2 100.0%
Branches: 14 18 77.8%

Line Branch Exec Source
1 /*******************************************************************************
2
3 License:
4 This software and/or related materials was developed at the National Institute
5 of Standards and Technology (NIST) by employees of the Federal Government
6 in the course of their official duties. Pursuant to title 17 Section 105
7 of the United States Code, this software is not subject to copyright
8 protection and is in the public domain.
9
10 This software and/or related materials have been determined to be not subject
11 to the EAR (see Part 734.3 of the EAR for exact details) because it is
12 a publicly available technology and software, and is freely distributed
13 to any interested party with no licensing requirements. Therefore, it is
14 permissible to distribute this software as a free download from the internet.
15
16 Disclaimer:
17 This software and/or related materials was developed to promote biometric
18 standards and biometric technology testing for the Federal Government
19 in accordance with the USA PATRIOT Act and the Enhanced Border Security
20 and Visa Entry Reform Act. Specific hardware and software products identified
21 in this software were used in order to perform the software development.
22 In no case does such identification imply recommendation or endorsement
23 by the National Institute of Standards and Technology, nor does it imply that
24 the products and equipment identified are necessarily the best available
25 for the purpose.
26
27 This software and/or related materials are provided "AS-IS" without warranty
28 of any kind including NO WARRANTY OF PERFORMANCE, MERCHANTABILITY,
29 NO WARRANTY OF NON-INFRINGEMENT OF ANY 3RD PARTY INTELLECTUAL PROPERTY
30 or FITNESS FOR A PARTICULAR PURPOSE or for any purpose whatsoever, for the
31 licensed product, however used. In no event shall NIST be liable for any
32 damages and/or costs, including but not limited to incidental or consequential
33 damages of any kind, including economic damage or injury to property and lost
34 profits, regardless of whether NIST shall be advised, have reason to know,
35 or in fact shall know of the possibility.
36
37 By using this software, you agree to bear all risk relating to quality,
38 use and performance of the software and/or related materials. You agree
39 to hold the Government harmless from any claim arising from your use
40 of the software.
41
42 *******************************************************************************/
43
44
45 /***********************************************************************
46 LIBRARY: LFS - NIST Latent Fingerprint System
47
48 FILE: CHAINCODE.C
49 AUTHOR: Michael D. Garris
50 DATE: 05/11/1999
51
52 Contains routines responsible for generating and manipulating
53 chain codes as part of the NIST Latent Fingerprint System (LFS).
54
55 ***********************************************************************
56 ROUTINES:
57 chain_code_loop()
58 is_chain_clockwise()
59 ***********************************************************************/
60
61 #include <stdio.h>
62 #include <lfs.h>
63
64 /*************************************************************************
65 **************************************************************************
66 #cat: chain_code_loop - Converts a feature's contour points into an
67 #cat: 8-connected chain code vector. This encoding represents
68 #cat: the direction taken between each adjacent point in the
69 #cat: contour. Chain codes may be used for many purposes, such
70 #cat: as computing the perimeter or area of an object, and they
71 #cat: may be used in object detection and recognition.
72
73 Input:
74 contour_x - x-coord list for feature's contour points
75 contour_y - y-coord list for feature's contour points
76 ncontour - number of points in contour
77 Output:
78 ochain - resulting vector of chain codes
79 onchain - number of codes in chain
80 (same as number of points in contour)
81 Return Code:
82 Zero - chain code successful derived
83 Negative - system error
84 **************************************************************************/
85 167 int chain_code_loop(int **ochain, int *onchain,
86 const int *contour_x, const int *contour_y, const int ncontour)
87 {
88 167 int *chain;
89 167 int i, j, dx, dy;
90
91 /* If we don't have at least 3 points in the contour ... */
92
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 167 times.
167 if(ncontour <= 3){
93 /* Then we don't have a loop, so set chain length to 0 */
94 /* and return without any allocations. */
95 *onchain = 0;
96 return(0);
97 }
98
99 /* Allocate chain code vector. It will be the same length as the */
100 /* number of points in the contour. There will be one chain code */
101 /* between each point on the contour including a code between the */
102 /* last to the first point on the contour (completing the loop). */
103 167 chain = (int *)g_malloc(ncontour * sizeof(int));
104
105 /* For each neighboring point in the list (with "i" pointing to the */
106 /* previous neighbor and "j" pointing to the next neighbor... */
107
2/2
✓ Branch 1 taken 1180 times.
✓ Branch 2 taken 167 times.
1514 for(i = 0, j=1; i < ncontour-1; i++, j++){
108 /* Compute delta in X between neighbors. */
109 1180 dx = contour_x[j] - contour_x[i];
110 /* Compute delta in Y between neighbors. */
111 1180 dy = contour_y[j] - contour_y[i];
112 /* Derive chain code index from neighbor deltas. */
113 /* The deltas are on the range [-1..1], so to use them as indices */
114 /* into the code list, they must first be incremented by one. */
115 1180 chain[i] = *(g_chaincodes_nbr8+((dy+1)*NBR8_DIM)+dx+1);
116 }
117
118 /* Now derive chain code between last and first points in the */
119 /* contour list. */
120 167 dx = contour_x[0] - contour_x[i];
121 167 dy = contour_y[0] - contour_y[i];
122 167 chain[i] = *(g_chaincodes_nbr8+((dy+1)*NBR8_DIM)+dx+1);
123
124 /* Store results to the output pointers. */
125 167 *ochain = chain;
126 167 *onchain = ncontour;
127
128 /* Return normally. */
129 167 return(0);
130 }
131
132 /*************************************************************************
133 **************************************************************************
134 #cat: is_chain_clockwise - Takes an 8-connected chain code vector and
135 #cat: determines if the codes are ordered clockwise or
136 #cat: counter-clockwise.
137 #cat: The routine also requires a default return value be
138 #cat: specified in the case the the routine is not able to
139 #cat: definitively determine the chains direction. This allows
140 #cat: the default response to be application-specific.
141
142 Input:
143 chain - chain code vector
144 nchain - number of codes in chain
145 default_ret - default return code (used when we can't tell the order)
146 Return Code:
147 TRUE - chain determined to be ordered clockwise
148 FALSE - chain determined to be ordered counter-clockwise
149 Default - could not determine the order of the chain
150 **************************************************************************/
151 167 int is_chain_clockwise(const int *chain, const int nchain,
152 const int default_ret)
153 {
154 167 int i, j, d, sum;
155
156 /* Initialize turn-accumulator to 0. */
157 167 sum = 0;
158
159 /* Foreach neighboring code in chain, compute the difference in */
160 /* direction and accumulate. Left-hand turns increment, whereas */
161 /* right-hand decrement. */
162
2/2
✓ Branch 0 taken 1180 times.
✓ Branch 1 taken 167 times.
1347 for(i = 0, j =1; i < nchain-1; i++, j++){
163 /* Compute delta in neighbor direction. */
164 1180 d = chain[j] - chain[i];
165 /* Make the delta the "inner" distance. */
166 /* If delta >= 4, for example if chain_i==2 and chain_j==7 (which */
167 /* means the contour went from a step up to step down-to-the-right) */
168 /* then 5=(7-2) which is >=4, so -3=(5-8) which means that the */
169 /* change in direction is a righ-hand turn of 3 units). */
170
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1177 times.
1180 if(d >= 4)
171 3 d -= 8;
172 /* If delta <= -4, for example if chain_i==7 and chain_j==2 (which */
173 /* means the contour went from a step down-to-the-right to step up) */
174 /* then -5=(2-7) which is <=-4, so 3=(-5+8) which means that the */
175 /* change in direction is a left-hand turn of 3 units). */
176
2/2
✓ Branch 0 taken 169 times.
✓ Branch 1 taken 1008 times.
1177 else if (d <= -4)
177 169 d += 8;
178
179 /* The delta direction is then accumulated. */
180 1180 sum += d;
181 }
182
183 /* Now we need to add in the final delta direction between the last */
184 /* and first codes in the chain. */
185 167 d = chain[0] - chain[i];
186
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 167 times.
167 if(d >= 4)
187 d -= 8;
188
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 166 times.
167 else if (d <= -4)
189 1 d += 8;
190 167 sum += d;
191
192 /* If the final turn_accumulator == 0, then we CAN'T TELL the */
193 /* direction of the chain code, so return the default return value. */
194
1/2
✓ Branch 0 taken 167 times.
✗ Branch 1 not taken.
167 if(sum == 0)
195 return(default_ret);
196 /* Otherwise, if the final turn-accumulator is positive ... */
197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 167 times.
167 else if(sum > 0)
198 /* Then we had a greater amount of left-hand turns than right-hand */
199 /* turns, so the chain is in COUNTER-CLOCKWISE order, so return FALSE. */
200 return(FALSE);
201 /* Otherwise, the final turn-accumulator is negative ... */
202 else
203 /* So we had a greater amount of right-hand turns than left-hand */
204 /* turns, so the chain is in CLOCKWISE order, so return TRUE. */
205 return(TRUE);
206 }
207