| 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: IMGUTIL.C | ||
| 49 | AUTHOR: Michael D. Garris | ||
| 50 | DATE: 03/16/1999 | ||
| 51 | UPDATED: 03/16/2005 by MDG | ||
| 52 | |||
| 53 | Contains general support image routines required by the NIST | ||
| 54 | Latent Fingerprint System (LFS). | ||
| 55 | |||
| 56 | *********************************************************************** | ||
| 57 | ROUTINES: | ||
| 58 | bits_6to8() | ||
| 59 | bits_8to6() | ||
| 60 | gray2bin() | ||
| 61 | pad_uchar_image() | ||
| 62 | fill_holes() | ||
| 63 | free_path() | ||
| 64 | search_in_direction() | ||
| 65 | |||
| 66 | ***********************************************************************/ | ||
| 67 | |||
| 68 | #include <stdio.h> | ||
| 69 | #include <memory.h> | ||
| 70 | #include <lfs.h> | ||
| 71 | |||
| 72 | /************************************************************************* | ||
| 73 | ************************************************************************** | ||
| 74 | #cat: bits_6to8 - Takes an array of unsigned characters and bitwise shifts | ||
| 75 | #cat: each value 2 postitions to the left. This is equivalent | ||
| 76 | #cat: to multiplying each value by 4. This puts original values | ||
| 77 | #cat: on the range [0..64) now on the range [0..256). Another | ||
| 78 | #cat: way to say this, is the original 6-bit values now fit in | ||
| 79 | #cat: 8 bits. This is to be used to undo the effects of bits_8to6. | ||
| 80 | |||
| 81 | Input: | ||
| 82 | idata - input array of unsigned characters | ||
| 83 | iw - width (in characters) of the input array | ||
| 84 | ih - height (in characters) of the input array | ||
| 85 | Output: | ||
| 86 | idata - contains the bit-shifted results | ||
| 87 | **************************************************************************/ | ||
| 88 | |||
| 89 | /************************************************************************* | ||
| 90 | ************************************************************************** | ||
| 91 | #cat: bits_8to6 - Takes an array of unsigned characters and bitwise shifts | ||
| 92 | #cat: each value 2 postitions to the right. This is equivalent | ||
| 93 | #cat: to dividing each value by 4. This puts original values | ||
| 94 | #cat: on the range [0..256) now on the range [0..64). Another | ||
| 95 | #cat: way to say this, is the original 8-bit values now fit in | ||
| 96 | #cat: 6 bits. I would really like to make this dependency | ||
| 97 | #cat: go away. | ||
| 98 | |||
| 99 | Input: | ||
| 100 | idata - input array of unsigned characters | ||
| 101 | iw - width (in characters) of the input array | ||
| 102 | ih - height (in characters) of the input array | ||
| 103 | Output: | ||
| 104 | idata - contains the bit-shifted results | ||
| 105 | **************************************************************************/ | ||
| 106 | 48 | void bits_8to6(unsigned char *idata, const int iw, const int ih) | |
| 107 | { | ||
| 108 | 48 | int i, isize; | |
| 109 | 48 | unsigned char *iptr; | |
| 110 | |||
| 111 | 48 | isize = iw * ih; | |
| 112 | 48 | iptr = idata; | |
| 113 |
2/2✓ Branch 0 (4→3) taken 3880414 times.
✓ Branch 1 (4→5) taken 48 times.
|
3880462 | for(i = 0; i < isize; i++){ |
| 114 | /* Divide every pixel value by 4 so that [0..256) -> [0..64) */ | ||
| 115 | 3880414 | *iptr++ >>= 2; | |
| 116 | } | ||
| 117 | 48 | } | |
| 118 | |||
| 119 | /************************************************************************* | ||
| 120 | ************************************************************************** | ||
| 121 | #cat: gray2bin - Takes an 8-bit threshold value and two 8-bit pixel values. | ||
| 122 | #cat: Those pixels in the image less than the threhsold are set | ||
| 123 | #cat: to the first specified pixel value, whereas those pixels | ||
| 124 | #cat: greater than or equal to the threshold are set to the second | ||
| 125 | #cat: specified pixel value. On application for this routine is | ||
| 126 | #cat: to convert binary images from 8-bit pixels valued {0,255} to | ||
| 127 | #cat: {1,0} and vice versa. | ||
| 128 | |||
| 129 | Input: | ||
| 130 | thresh - 8-bit pixel threshold | ||
| 131 | less_pix - pixel value used when image pixel is < threshold | ||
| 132 | greater_pix - pixel value used when image pixel is >= threshold | ||
| 133 | bdata - 8-bit image data | ||
| 134 | iw - width (in pixels) of the image | ||
| 135 | ih - height (in pixels) of the image | ||
| 136 | Output: | ||
| 137 | bdata - altered 8-bit image data | ||
| 138 | **************************************************************************/ | ||
| 139 | 96 | void gray2bin(const int thresh, const int less_pix, const int greater_pix, | |
| 140 | unsigned char *bdata, const int iw, const int ih) | ||
| 141 | { | ||
| 142 | 96 | int i; | |
| 143 | |||
| 144 |
2/2✓ Branch 0 (7→3) taken 6383192 times.
✓ Branch 1 (7→8) taken 96 times.
|
6383288 | for(i = 0; i < iw*ih; i++){ |
| 145 |
2/2✓ Branch 0 (3→4) taken 3193951 times.
✓ Branch 1 (3→5) taken 3189241 times.
|
6383192 | if(bdata[i] >= thresh) |
| 146 | 3193951 | bdata[i] = (unsigned char)greater_pix; | |
| 147 | else | ||
| 148 | 3189241 | bdata[i] = (unsigned char)less_pix; | |
| 149 | } | ||
| 150 | 96 | } | |
| 151 | |||
| 152 | /************************************************************************* | ||
| 153 | ************************************************************************** | ||
| 154 | #cat: pad_uchar_image - Copies an 8-bit grayscale images into a larger | ||
| 155 | #cat: output image centering the input image so as to | ||
| 156 | #cat: add a specified amount of pixel padding along the | ||
| 157 | #cat: entire perimeter of the input image. The amount of | ||
| 158 | #cat: pixel padding and the intensity of the pixel padding | ||
| 159 | #cat: are specified. An alternative to padding with a | ||
| 160 | #cat: constant intensity would be to copy the edge pixels | ||
| 161 | #cat: of the centered image into the adjacent pad area. | ||
| 162 | |||
| 163 | Input: | ||
| 164 | idata - input 8-bit grayscale image | ||
| 165 | iw - width (in pixels) of the input image | ||
| 166 | ih - height (in pixels) of the input image | ||
| 167 | pad - size of padding (in pixels) to be added | ||
| 168 | pad_value - intensity of the padded area | ||
| 169 | Output: | ||
| 170 | optr - points to the newly padded image | ||
| 171 | ow - width (in pixels) of the padded image | ||
| 172 | oh - height (in pixels) of the padded image | ||
| 173 | Return Code: | ||
| 174 | Zero - successful completion | ||
| 175 | Negative - system error | ||
| 176 | **************************************************************************/ | ||
| 177 | 48 | int pad_uchar_image(unsigned char **optr, int *ow, int *oh, | |
| 178 | unsigned char *idata, const int iw, const int ih, | ||
| 179 | const int pad, const int pad_value) | ||
| 180 | { | ||
| 181 | 48 | unsigned char *pdata, *pptr, *iptr; | |
| 182 | 48 | int i, pw, ph; | |
| 183 | 48 | int pad2, psize; | |
| 184 | |||
| 185 | /* Account for pad on both sides of image */ | ||
| 186 | 48 | pad2 = pad<<1; | |
| 187 | |||
| 188 | /* Compute new pad sizes */ | ||
| 189 | 48 | pw = iw + pad2; | |
| 190 | 48 | ph = ih + pad2; | |
| 191 | 48 | psize = pw * ph; | |
| 192 | |||
| 193 | /* Allocate padded image */ | ||
| 194 | 48 | pdata = (unsigned char *)g_malloc(psize * sizeof(unsigned char)); | |
| 195 | |||
| 196 | /* Initialize values to a constant PAD value */ | ||
| 197 | 48 | memset(pdata, pad_value, psize); | |
| 198 | |||
| 199 | /* Copy input image into padded image one scanline at a time */ | ||
| 200 | 48 | iptr = idata; | |
| 201 | 48 | pptr = pdata + (pad * pw) + pad; | |
| 202 |
2/2✓ Branch 0 (5→4) taken 13261 times.
✓ Branch 1 (5→6) taken 48 times.
|
13309 | for(i = 0; i < ih; i++){ |
| 203 | 13261 | memcpy(pptr, iptr, iw); | |
| 204 | 13261 | iptr += iw; | |
| 205 | 13261 | pptr += pw; | |
| 206 | } | ||
| 207 | |||
| 208 | 48 | *optr = pdata; | |
| 209 | 48 | *ow = pw; | |
| 210 | 48 | *oh = ph; | |
| 211 | 48 | return(0); | |
| 212 | } | ||
| 213 | |||
| 214 | /************************************************************************* | ||
| 215 | ************************************************************************** | ||
| 216 | #cat: fill_holes - Takes an input image and analyzes triplets of horizontal | ||
| 217 | #cat: pixels first and then triplets of vertical pixels, filling | ||
| 218 | #cat: in holes of width 1. A hole is defined as the case where | ||
| 219 | #cat: the neighboring 2 pixels are equal, AND the center pixel | ||
| 220 | #cat: is different. Each hole is filled with the value of its | ||
| 221 | #cat: immediate neighbors. This routine modifies the input image. | ||
| 222 | |||
| 223 | Input: | ||
| 224 | bdata - binary image data to be processed | ||
| 225 | iw - width (in pixels) of the binary input image | ||
| 226 | ih - height (in pixels) of the binary input image | ||
| 227 | Output: | ||
| 228 | bdata - points to the results | ||
| 229 | **************************************************************************/ | ||
| 230 | 144 | void fill_holes(unsigned char *bdata, const int iw, const int ih) | |
| 231 | { | ||
| 232 | 144 | int ix, iy, iw2; | |
| 233 | 144 | unsigned char *lptr, *mptr, *rptr, *tptr, *bptr, *sptr; | |
| 234 | |||
| 235 | /* 1. Fill 1-pixel wide holes in horizontal runs first ... */ | ||
| 236 | 144 | sptr = bdata + 1; | |
| 237 | /* Foreach row in image ... */ | ||
| 238 |
2/2✓ Branch 0 (11→3) taken 39783 times.
✓ Branch 1 (11→12) taken 144 times.
|
39927 | for(iy = 0; iy < ih; iy++){ |
| 239 | /* Initialize pointers to start of next line ... */ | ||
| 240 | 39783 | lptr = sptr-1; /* Left pixel */ | |
| 241 | 39783 | mptr = sptr; /* Middle pixel */ | |
| 242 | 39783 | rptr = sptr+1; /* Right pixel */ | |
| 243 | /* Foreach column in image (less far left and right pixels) ... */ | ||
| 244 |
2/2✓ Branch 0 (9→4) taken 9451777 times.
✓ Branch 1 (9→10) taken 39783 times.
|
9491560 | for(ix = 1; ix < iw-1; ix++){ |
| 245 | /* Do we have a horizontal hole of length 1? */ | ||
| 246 |
4/4✓ Branch 0 (4→5) taken 1365623 times.
✓ Branch 1 (4→7) taken 8086154 times.
✓ Branch 2 (5→6) taken 43445 times.
✓ Branch 3 (5→7) taken 1322178 times.
|
9451777 | if((*lptr != *mptr) && (*lptr == *rptr)){ |
| 247 | /* If so, then fill it. */ | ||
| 248 | 43445 | *mptr = *lptr; | |
| 249 | /* Bump passed right pixel because we know it will not */ | ||
| 250 | /* be a hole. */ | ||
| 251 | 43445 | lptr+=2; | |
| 252 | 43445 | mptr+=2; | |
| 253 | 43445 | rptr+=2; | |
| 254 | /* We bump ix once here and then the FOR bumps it again. */ | ||
| 255 | 43445 | ix++; | |
| 256 | } | ||
| 257 | else{ | ||
| 258 | /* Otherwise, bump to the next pixel to the right. */ | ||
| 259 | 9408332 | lptr++; | |
| 260 | 9408332 | mptr++; | |
| 261 | 9408332 | rptr++; | |
| 262 | } | ||
| 263 | } | ||
| 264 | /* Bump to start of next row. */ | ||
| 265 | 39783 | sptr += iw; | |
| 266 | } | ||
| 267 | |||
| 268 | /* 2. Now, fill 1-pixel wide holes in vertical runs ... */ | ||
| 269 | 144 | iw2 = iw<<1; | |
| 270 | /* Start processing column one row down from the top of the image. */ | ||
| 271 | 144 | sptr = bdata + iw; | |
| 272 | /* Foreach column in image ... */ | ||
| 273 |
2/2✓ Branch 0 (21→13) taken 35952 times.
✓ Branch 1 (21→22) taken 144 times.
|
36096 | for(ix = 0; ix < iw; ix++){ |
| 274 | /* Initialize pointers to start of next column ... */ | ||
| 275 | 35952 | tptr = sptr-iw; /* Top pixel */ | |
| 276 | 35952 | mptr = sptr; /* Middle pixel */ | |
| 277 | 35952 | bptr = sptr+iw; /* Bottom pixel */ | |
| 278 | /* Foreach row in image (less top and bottom row) ... */ | ||
| 279 |
2/2✓ Branch 0 (19→14) taken 9453817 times.
✓ Branch 1 (19→20) taken 35952 times.
|
9489769 | for(iy = 1; iy < ih-1; iy++){ |
| 280 | /* Do we have a vertical hole of length 1? */ | ||
| 281 |
4/4✓ Branch 0 (14→15) taken 1679955 times.
✓ Branch 1 (14→17) taken 7773862 times.
✓ Branch 2 (15→16) taken 49067 times.
✓ Branch 3 (15→17) taken 1630888 times.
|
9453817 | if((*tptr != *mptr) && (*tptr == *bptr)){ |
| 282 | /* If so, then fill it. */ | ||
| 283 | 49067 | *mptr = *tptr; | |
| 284 | /* Bump passed bottom pixel because we know it will not */ | ||
| 285 | /* be a hole. */ | ||
| 286 | 49067 | tptr+=iw2; | |
| 287 | 49067 | mptr+=iw2; | |
| 288 | 49067 | bptr+=iw2; | |
| 289 | /* We bump iy once here and then the FOR bumps it again. */ | ||
| 290 | 49067 | iy++; | |
| 291 | } | ||
| 292 | else{ | ||
| 293 | /* Otherwise, bump to the next pixel below. */ | ||
| 294 | 9404750 | tptr+=iw; | |
| 295 | 9404750 | mptr+=iw; | |
| 296 | 9404750 | bptr+=iw; | |
| 297 | } | ||
| 298 | } | ||
| 299 | /* Bump to start of next column. */ | ||
| 300 | 35952 | sptr++; | |
| 301 | } | ||
| 302 | 144 | } | |
| 303 | |||
| 304 | /************************************************************************* | ||
| 305 | ************************************************************************** | ||
| 306 | #cat: free_path - Traverses a straight line between 2 pixel points in an | ||
| 307 | #cat: image and determines if a "free path" exists between the | ||
| 308 | #cat: 2 points by counting the number of pixel value transitions | ||
| 309 | #cat: between adjacent pixels along the trajectory. | ||
| 310 | |||
| 311 | Input: | ||
| 312 | x1 - x-pixel coord of first point | ||
| 313 | y1 - y-pixel coord of first point | ||
| 314 | x2 - x-pixel coord of second point | ||
| 315 | y2 - y-pixel coord of second point | ||
| 316 | bdata - binary image data (0==while & 1==black) | ||
| 317 | iw - width (in pixels) of image | ||
| 318 | ih - height (in pixels) of image | ||
| 319 | lfsparms - parameters and threshold for controlling LFS | ||
| 320 | Return Code: | ||
| 321 | TRUE - free path determined to exist | ||
| 322 | FALSE - free path determined not to exist | ||
| 323 | Negative - system error | ||
| 324 | **************************************************************************/ | ||
| 325 | 795 | int free_path(const int x1, const int y1, const int x2, const int y2, | |
| 326 | unsigned char *bdata, const int iw, const int ih, | ||
| 327 | const LFSPARMS *lfsparms) | ||
| 328 | { | ||
| 329 | 795 | int *x_list, *y_list, num; | |
| 330 | 795 | int ret; | |
| 331 | 795 | int i, trans, preval, nextval; | |
| 332 | |||
| 333 | /* Compute points along line segment between the two points. */ | ||
| 334 |
1/2✓ Branch 0 (3→4) taken 795 times.
✗ Branch 1 (3→15) not taken.
|
795 | if((ret = line_points(&x_list, &y_list, &num, x1, y1, x2, y2))) |
| 335 | return(ret); | ||
| 336 | |||
| 337 | /* Intialize the number of transitions to 0. */ | ||
| 338 | 795 | trans = 0; | |
| 339 | /* Get the pixel value of first point along line segment. */ | ||
| 340 | 795 | preval = *(bdata+(y1*iw)+x1); | |
| 341 | |||
| 342 | /* Foreach remaining point along line segment ... */ | ||
| 343 |
2/2✓ Branch 0 (11→5) taken 3324 times.
✓ Branch 1 (11→12) taken 742 times.
|
4066 | for(i = 1; i < num; i++){ |
| 344 | /* Get pixel value of next point along line segment. */ | ||
| 345 | 3324 | nextval = *(bdata+(y_list[i]*iw)+x_list[i]); | |
| 346 | |||
| 347 | /* If next pixel value different from previous pixel value ... */ | ||
| 348 |
2/2✓ Branch 0 (5→6) taken 1643 times.
✓ Branch 1 (5→10) taken 1681 times.
|
3324 | if(nextval != preval){ |
| 349 | /* Then we have detected a transition, so bump counter. */ | ||
| 350 | 1643 | trans++; | |
| 351 | /* If number of transitions seen > than threshold (ex. 2) ... */ | ||
| 352 |
2/2✓ Branch 0 (6→7) taken 53 times.
✓ Branch 1 (6→10) taken 1590 times.
|
1643 | if(trans > lfsparms->maxtrans){ |
| 353 | /* Deallocate the line segment's coordinate lists. */ | ||
| 354 | 53 | g_free(x_list); | |
| 355 | 53 | g_free(y_list); | |
| 356 | /* Return free path to be FALSE. */ | ||
| 357 | 53 | return(FALSE); | |
| 358 | } | ||
| 359 | /* Otherwise, maximum number of transitions not yet exceeded. */ | ||
| 360 | /* Assign the next pixel value to the previous pixel value. */ | ||
| 361 | preval = nextval; | ||
| 362 | } | ||
| 363 | /* Otherwise, no transition detected this interation. */ | ||
| 364 | |||
| 365 | } | ||
| 366 | |||
| 367 | /* If we get here we did not exceed the maximum allowable number */ | ||
| 368 | /* of transitions. So, deallocate the line segment's coordinate lists. */ | ||
| 369 | 742 | g_free(x_list); | |
| 370 | 742 | g_free(y_list); | |
| 371 | |||
| 372 | /* Return free path to be TRUE. */ | ||
| 373 | 742 | return(TRUE); | |
| 374 | } | ||
| 375 | |||
| 376 | /************************************************************************* | ||
| 377 | ************************************************************************** | ||
| 378 | #cat: search_in_direction - Takes a specified maximum number of steps in a | ||
| 379 | #cat: specified direction looking for the first occurence of | ||
| 380 | #cat: a pixel with specified value. (Once found, adjustments | ||
| 381 | #cat: are potentially made to make sure the resulting pixel | ||
| 382 | #cat: and its associated edge pixel are 4-connected.) | ||
| 383 | |||
| 384 | Input: | ||
| 385 | pix - value of pixel to be searched for | ||
| 386 | strt_x - x-pixel coord to start search | ||
| 387 | strt_y - y-pixel coord to start search | ||
| 388 | delta_x - increment in x for each step | ||
| 389 | delta_y - increment in y for each step | ||
| 390 | maxsteps - maximum number of steps to conduct search | ||
| 391 | bdata - binary image data (0==while & 1==black) | ||
| 392 | iw - width (in pixels) of image | ||
| 393 | ih - height (in pixels) of image | ||
| 394 | Output: | ||
| 395 | ox - x coord of located pixel | ||
| 396 | oy - y coord of located pixel | ||
| 397 | oex - x coord of associated edge pixel | ||
| 398 | oey - y coord of associated edge pixel | ||
| 399 | Return Code: | ||
| 400 | TRUE - pixel of specified value found | ||
| 401 | FALSE - pixel of specified value NOT found | ||
| 402 | **************************************************************************/ | ||
| 403 | 4634 | int search_in_direction(int *ox, int *oy, int *oex, int *oey, const int pix, | |
| 404 | const int strt_x, const int strt_y, | ||
| 405 | const double delta_x, const double delta_y, const int maxsteps, | ||
| 406 | unsigned char *bdata, const int iw, const int ih) | ||
| 407 | { | ||
| 408 | |||
| 409 | 4634 | int i, x, y, px, py; | |
| 410 | 4634 | double fx, fy; | |
| 411 | |||
| 412 | /* Set previous point to starting point. */ | ||
| 413 | 4634 | px = strt_x; | |
| 414 | 4634 | py = strt_y; | |
| 415 | /* Set floating point accumulators to starting point. */ | ||
| 416 | 4634 | fx = (double)strt_x; | |
| 417 | 4634 | fy = (double)strt_y; | |
| 418 | |||
| 419 | /* Foreach step up to the specified maximum ... */ | ||
| 420 |
2/2✓ Branch 0 (17→3) taken 20363 times.
✓ Branch 1 (17→18) taken 153 times.
|
20516 | for(i = 0; i < maxsteps; i++){ |
| 421 | |||
| 422 | /* Increment accumulators. */ | ||
| 423 | 20363 | fx += delta_x; | |
| 424 | 20363 | fy += delta_y; | |
| 425 | /* Round to get next step. */ | ||
| 426 |
2/2✓ Branch 0 (3→4) taken 15 times.
✓ Branch 1 (3→5) taken 20348 times.
|
20363 | x = sround(fx); |
| 427 |
2/2✓ Branch 0 (6→7) taken 38 times.
✓ Branch 1 (6→8) taken 20325 times.
|
20363 | y = sround(fy); |
| 428 | |||
| 429 | /* If we stepped outside the image boundaries ... */ | ||
| 430 |
2/2✓ Branch 0 (9→10) taken 20348 times.
✓ Branch 1 (9→11) taken 15 times.
|
20363 | if((x < 0) || (x >= iw) || |
| 431 |
2/2✓ Branch 0 (10→11) taken 21 times.
✓ Branch 1 (10→13) taken 20327 times.
|
20348 | (y < 0) || (y >= ih)){ |
| 432 | /* Return FALSE (we did not find what we were looking for). */ | ||
| 433 | 36 | *ox = -1; | |
| 434 | 36 | *oy = -1; | |
| 435 | 36 | *oex = -1; | |
| 436 | 36 | *oey = -1; | |
| 437 | 36 | return(FALSE); | |
| 438 | } | ||
| 439 | |||
| 440 | /* Otherwise, test to see if we found our pixel with value 'pix'. */ | ||
| 441 |
2/2✓ Branch 0 (13→14) taken 4445 times.
✓ Branch 1 (13→16) taken 15882 times.
|
20327 | if(*(bdata+(y*iw)+x) == pix){ |
| 442 | /* The previous and current pixels form a feature, edge pixel */ | ||
| 443 | /* pair, which we would like to use for edge following. The */ | ||
| 444 | /* previous pixel may be a diagonal neighbor however to the */ | ||
| 445 | /* current pixel, in which case the pair could not be used by */ | ||
| 446 | /* the contour tracing (which requires the edge pixel in the */ | ||
| 447 | /* pair neighbor to the N,S,E or W. */ | ||
| 448 | /* This routine adjusts the pair so that the results may be */ | ||
| 449 | /* used by the contour tracing. */ | ||
| 450 | 4445 | fix_edge_pixel_pair(&x, &y, &px, &py, bdata, iw, ih); | |
| 451 | |||
| 452 | /* Return TRUE (we found what we were looking for). */ | ||
| 453 | 4445 | *ox = x; | |
| 454 | 4445 | *oy = y; | |
| 455 | 4445 | *oex = px; | |
| 456 | 4445 | *oey = py; | |
| 457 | 4445 | return(TRUE); | |
| 458 | } | ||
| 459 | |||
| 460 | /* Otherwise, still haven't found pixel with desired value, */ | ||
| 461 | /* so set current point to previous and take another step. */ | ||
| 462 | 15882 | px = x; | |
| 463 | 15882 | py = y; | |
| 464 | } | ||
| 465 | |||
| 466 | /* Return FALSE (we did not find what we were looking for). */ | ||
| 467 | 153 | *ox = -1; | |
| 468 | 153 | *oy = -1; | |
| 469 | 153 | *oex = -1; | |
| 470 | 153 | *oey = -1; | |
| 471 | 153 | return(FALSE); | |
| 472 | } | ||
| 473 | |||
| 474 |