GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 94.6% 139 / 0 / 147
Functions: 100.0% 6 / 0 / 6
Branches: 76.4% 42 / 0 / 55

libfprint/nbis/mindtct/init.c
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: INIT.C
49 AUTHOR: Michael D. Garris
50 DATE: 03/16/1999
51 UPDATED: 10/04/1999 Version 2 by MDG
52 UPDATED: 03/16/2005 by MDG
53
54 Contains routines responsible for allocation and/or initialization
55 of memories required by the NIST Latent Fingerprint System.
56
57 ***********************************************************************
58 ROUTINES:
59 init_dir2rad()
60 init_dftwaves()
61 get_max_padding()
62 get_max_padding_V2()
63 init_rotgrids()
64 alloc_dir_powers()
65 alloc_power_stats()
66 ***********************************************************************/
67
68 #include <stdio.h>
69 #include <lfs.h>
70
71 /*************************************************************************
72 **************************************************************************
73 #cat: init_dir2rad - Allocates and initializes a lookup table containing
74 #cat: cosine and sine values needed to convert integer IMAP
75 #cat: directions to angles in radians.
76
77 Input:
78 ndirs - the number of integer directions to be defined in a
79 semicircle
80 Output:
81 optr - points to the allocated/initialized DIR2RAD structure
82 Return Code:
83 Zero - successful completion
84 Negative - system error
85 **************************************************************************/
86 50 int init_dir2rad(DIR2RAD **optr, const int ndirs)
87 {
88 50 DIR2RAD *dir2rad;
89 50 int i;
90 50 double theta, pi_factor;
91 50 double cs, sn;
92
93 /* Allocate structure */
94 50 dir2rad = (DIR2RAD *)g_malloc(sizeof(DIR2RAD));
95
96 /* Assign number of directions */
97 50 dir2rad->ndirs = ndirs;
98
99 /* Allocate cosine vector */
100 50 dir2rad->cos = (double *)g_malloc(ndirs * sizeof(double));
101
102 /* Allocate sine vector */
103 50 dir2rad->sin = (double *)g_malloc(ndirs * sizeof(double));
104
105 /* Pi_factor sets the period of the trig functions to NDIRS units in x. */
106 /* For example, if NDIRS==16, then pi_factor = 2(PI/16) = .3926... */
107 50 pi_factor = 2.0*M_PI/(double)ndirs;
108
109 /* Now compute cos and sin values for each direction. */
110
2/2
✓ Branch 13 → 6 taken 800 times.
✓ Branch 13 → 14 taken 50 times.
850 for (i = 0; i < ndirs; ++i) {
111 800 theta = (double)(i * pi_factor);
112 800 cs = cos(theta);
113 800 sn = sin(theta);
114 /* Need to truncate precision so that answers are consistent */
115 /* on different computer architectures. */
116
2/2
✓ Branch 6 → 7 taken 400 times.
✓ Branch 6 → 8 taken 400 times.
800 cs = trunc_dbl_precision(cs, TRUNC_SCALE);
117
2/2
✓ Branch 9 → 10 taken 350 times.
✓ Branch 9 → 11 taken 450 times.
800 sn = trunc_dbl_precision(sn, TRUNC_SCALE);
118 800 dir2rad->cos[i] = cs;
119 800 dir2rad->sin[i] = sn;
120 }
121
122 50 *optr = dir2rad;
123 50 return(0);
124 }
125
126 /*************************************************************************
127 **************************************************************************
128 #cat: init_dftwaves - Allocates and initializes a set of wave forms needed
129 #cat: to conduct DFT analysis on blocks of the input image
130
131 Input:
132 dft_coefs - array of multipliers used to define the frequency for
133 each wave form to be computed
134 nwaves - number of wave forms to be computed
135 blocksize - the width and height of each block of image data to
136 be DFT analyzed
137 Output:
138 optr - points to the allocated/initialized DFTWAVES structure
139 Return Code:
140 Zero - successful completion
141 Negative - system error
142 **************************************************************************/
143 50 int init_dftwaves(DFTWAVES **optr, const double *dft_coefs,
144 const int nwaves, const int blocksize)
145 {
146 50 DFTWAVES *dftwaves;
147 50 int i, j;
148 50 double pi_factor, freq, x;
149 50 double *cptr, *sptr;
150
151 /* Allocate structure */
152 50 dftwaves = (DFTWAVES *)g_malloc(sizeof(DFTWAVES));
153
154 /* Set number of DFT waves */
155 50 dftwaves->nwaves = nwaves;
156 /* Set wave length of the DFT waves (they all must be the same length) */
157 50 dftwaves->wavelen = blocksize;
158
159 /* Allocate list of wave pointers */
160 50 dftwaves->waves = (DFTWAVE **)g_malloc(nwaves * sizeof(DFTWAVE *));
161 50 if(dftwaves == (DFTWAVES *)NULL){
162 /* Free memory allocated to this point. */
163 g_free(dftwaves);
164 fprintf(stderr, "ERROR : init_dftwaves : malloc : dftwaves->waves\n");
165 return(-21);
166 }
167
168 /* Pi_factor sets the period of the trig functions to BLOCKSIZE units */
169 /* in x. For example, if BLOCKSIZE==24, then */
170 /* pi_factor = 2(PI/24) = .26179... */
171 50 pi_factor = 2.0*M_PI/(double)blocksize;
172
173 /* Foreach of 4 DFT frequency coef ... */
174
2/2
✓ Branch 12 → 5 taken 200 times.
✓ Branch 12 → 13 taken 50 times.
250 for (i = 0; i < nwaves; ++i) {
175 /* Allocate wave structure */
176 200 dftwaves->waves[i] = (DFTWAVE *)g_malloc(sizeof(DFTWAVE));
177 /* Allocate cosine vector */
178 200 dftwaves->waves[i]->cos = (double *)g_malloc(blocksize * sizeof(double));
179 /* Allocate sine vector */
180 200 dftwaves->waves[i]->sin = (double *)g_malloc(blocksize * sizeof(double));
181
182 /* Assign pointer nicknames */
183 200 cptr = dftwaves->waves[i]->cos;
184 200 sptr = dftwaves->waves[i]->sin;
185
186 /* Compute actual frequency */
187 200 freq = pi_factor * dft_coefs[i];
188
189 /* Used as a 1D DFT on a 24 long vector of pixel sums */
190
2/2
✓ Branch 10 → 9 taken 4800 times.
✓ Branch 10 → 11 taken 200 times.
5000 for (j = 0; j < blocksize; ++j) {
191 /* Compute sample points from frequency */
192 4800 x = freq * (double)j;
193 /* Store cos and sin components of sample point */
194 4800 *cptr++ = cos(x);
195 4800 *sptr++ = sin(x);
196 }
197 }
198
199 50 *optr = dftwaves;
200 50 return(0);
201 }
202
203 /*************************************************************************
204 **************************************************************************
205 #cat: get_max_padding - Deterines the maximum amount of image pixel padding
206 #cat: required by all LFS processes. Padding is currently
207 #cat: required by the rotated grids used in DFT analyses,
208 #cat: rotated grids used in directional binarization,
209 #cat: and in the grid used for isotropic binarization.
210 #cat: The NIST generalized code enables the parameters
211 #cat: governing these processes to be redefined, so a check
212 #cat: at runtime is required to determine which process
213 #cat: requires the most padding. By using the maximum as
214 #cat: the padding factor, all processes will run safely
215 #cat: with a single padding of the input image avoiding the
216 #cat: need to repad for further processes.
217
218 Input:
219 imap_blocksize - the size (in pixels) of each IMAP block in the image
220 dirbin_grid_w - the width (in pixels) of the rotated grids used in
221 directional binarization
222 dirbin_grid_h - the height (in pixels) of the rotated grids used in
223 directional binarization
224 isobin_grid_dim - the dimension (in pixels) of the square grid used in
225 isotropic binarization
226 Return Code:
227 Non-negative - the maximum padding required for all processes
228 **************************************************************************/
229
230 /*************************************************************************
231 **************************************************************************
232 #cat: get_max_padding_V2 - Deterines the maximum amount of image pixel padding
233 #cat: required by all LFS (Version 2) processes. Padding is currently
234 #cat: required by the rotated grids used in DFT analyses and in
235 #cat: directional binarization. The NIST generalized code enables
236 #cat: the parameters governing these processes to be redefined, so a
237 #cat: check at runtime is required to determine which process
238 #cat: requires the most padding. By using the maximum as the padding
239 #cat: factor, all processes will run safely with a single padding of
240 #cat: the input image avoiding the need to repad for further processes.
241
242 Input:
243 map_windowsize - the size (in pixels) of each window centered about
244 each block in the image used in DFT analyses
245 map_windowoffset - the offset (in pixels) from the orgin of the
246 surrounding window to the origin of the block
247 dirbin_grid_w - the width (in pixels) of the rotated grids used in
248 directional binarization
249 dirbin_grid_h - the height (in pixels) of the rotated grids used in
250 directional binarization
251 Return Code:
252 Non-negative - the maximum padding required for all processes
253 **************************************************************************/
254 50 int get_max_padding_V2(const int map_windowsize, const int map_windowoffset,
255 const int dirbin_grid_w, const int dirbin_grid_h)
256 {
257 50 int dft_pad, dirbin_pad, max_pad;
258 50 double diag;
259 50 double pad;
260
261
262 /* 1. Compute pad required for rotated windows used in DFT analyses. */
263
264 /* Explanation of DFT padding:
265
266 B---------------------
267 | window |
268 | |
269 | |
270 | A.......______|__________
271 | : : |
272 |<-C-->: block: |
273 <--|--D-->: : | image
274 | ........ |
275 | | |
276 | | |
277 | | |
278 ----------------------
279 |
280 |
281 |
282
283 Pixel A = Origin of entire fingerprint image
284 = Also origin of first block in image. Each pixel in
285 this block gets the same DFT results computed from
286 the surrounding window. Note that in general
287 blocks are adjacent and non-overlapping.
288
289 Pixel B = Origin of surrounding window in which DFT
290 analysis is conducted. Note that this window is not
291 completely contained in the image but extends to the
292 top and to the right.
293
294 Distance C = Number of pixels in which the window extends
295 beyond the image (map_windowoffset).
296
297 Distance D = Amount of padding required to hold the entire
298 rotated window in memory.
299
300 */
301
302 /* Compute pad as difference between the MAP windowsize */
303 /* and the diagonal distance of the window. */
304 /* (DFT grids are computed with pixel offsets RELATIVE2ORIGIN.) */
305 50 diag = sqrt((double)(2.0 * map_windowsize * map_windowsize));
306 50 pad = (diag-map_windowsize)/(double)2.0;
307 /* Need to truncate precision so that answers are consistent */
308 /* on different computer architectures when rounding doubles. */
309
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 50 times.
50 pad = trunc_dbl_precision(pad, TRUNC_SCALE);
310 /* Must add the window offset to the rotational padding. */
311
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 50 times.
50 dft_pad = sround(pad) + map_windowoffset;
312
313 /* 2. Compute pad required for rotated blocks used in directional */
314 /* binarization. Binarization blocks are applied to each pixel */
315 /* in the input image. */
316 50 diag = sqrt((double)((dirbin_grid_w*dirbin_grid_w)+
317 50 (dirbin_grid_h*dirbin_grid_h)));
318 /* Assumption: all grid centers reside in valid/allocated memory. */
319 /* (Dirbin grids are computed with pixel offsets RELATIVE2CENTER.) */
320 50 pad = (diag-1)/(double)2.0;
321 /* Need to truncate precision so that answers are consistent */
322 /* on different computer architectures when rounding doubles. */
323
1/2
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 50 times.
50 pad = trunc_dbl_precision(pad, TRUNC_SCALE);
324
1/2
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 50 times.
50 dirbin_pad = sround(pad);
325
326 50 max_pad = max(dft_pad, dirbin_pad);
327
328 /* Return the maximum of the two required paddings. This padding will */
329 /* be sufficiently large for all purposes, so that padding of the */
330 /* input image will only be required once. */
331 50 return(max_pad);
332 }
333
334 /*************************************************************************
335 **************************************************************************
336 #cat: init_rotgrids - Allocates and initializes a set of offsets that address
337 #cat: individual rotated pixels within a grid.
338 #cat: These rotated grids are used to conduct DFT analyses
339 #cat: on blocks of input image data, and they are used
340 #cat: in isotropic binarization.
341
342 Input:
343 iw - width (in pixels) of the input image
344 ih - height (in pixels) of the input image
345 pad - designates the number of pixels to be padded to the perimeter
346 of the input image. May be passed as UNDEFINED, in which
347 case the specific padding required by the rotated grids
348 will be computed and returned in ROTGRIDS.
349 start_dir_angle - angle from which rotations are to start
350 ndirs - number of rotations to compute (within a semicircle)
351 grid_w - width of the grid in pixels to be rotated
352 grid_h - height of the grid in pixels to be rotated
353 relative2 - designates whether pixel offsets whould be computed
354 relative to the ORIGIN or the CENTER of the grid
355 Output:
356 optr - points to the allcated/initialized ROTGRIDS structure
357 Return Code:
358 Zero - successful completion
359 Negative - system error
360 **************************************************************************/
361 100 int init_rotgrids(ROTGRIDS **optr, const int iw, const int ih, const int ipad,
362 const double start_dir_angle, const int ndirs,
363 const int grid_w, const int grid_h, const int relative2)
364 {
365 100 ROTGRIDS *rotgrids;
366 100 double pi_offset, pi_incr;
367 100 int dir, ix, iy, grid_size, pw, grid_pad, min_dim;
368 100 int *grid;
369 100 double diag, theta, cs, sn, cx, cy;
370 100 double fxm, fym, fx, fy;
371 100 int ixt, iyt;
372 100 double pad;
373
374 /* Allocate structure */
375 100 rotgrids = (ROTGRIDS *)g_malloc(sizeof(ROTGRIDS));
376
377 /* Set rotgrid attributes */
378 100 rotgrids->ngrids = ndirs;
379 100 rotgrids->grid_w = grid_w;
380 100 rotgrids->grid_h = grid_h;
381 100 rotgrids->start_angle = start_dir_angle;
382 100 rotgrids->relative2 = relative2;
383
384 /* Compute pad based on diagonal of the grid */
385 100 diag = sqrt((double)((grid_w*grid_w)+(grid_h*grid_h)));
386
2/3
✓ Branch 3 → 4 taken 50 times.
✓ Branch 3 → 10 taken 50 times.
✗ Branch 3 → 16 not taken.
100 switch(relative2){
387 50 case RELATIVE2CENTER:
388 /* Assumption: all grid centers reside in valid/allocated memory. */
389 50 pad = (diag-1)/(double)2.0;
390 /* Need to truncate precision so that answers are consistent */
391 /* on different computer architectures when rounding doubles. */
392
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 50 times.
50 pad = trunc_dbl_precision(pad, TRUNC_SCALE);
393
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 50 times.
50 grid_pad = sround(pad);
394 break;
395 50 case RELATIVE2ORIGIN:
396 /* Assumption: all grid origins reside in valid/allocated memory. */
397 50 min_dim = min(grid_w, grid_h);
398 /* Compute pad as difference between the smallest grid dimension */
399 /* and the diagonal distance of the grid. */
400 50 pad = (diag-min_dim)/(double)2.0;
401 /* Need to truncate precision so that answers are consistent */
402 /* on different computer architectures when rounding doubles. */
403
1/2
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 50 times.
50 pad = trunc_dbl_precision(pad, TRUNC_SCALE);
404
1/2
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 15 taken 50 times.
50 grid_pad = sround(pad);
405 break;
406 default:
407 fprintf(stderr,
408 "ERROR : init_rotgrids : Illegal relative flag : %d\n",
409 relative2);
410 g_free(rotgrids);
411 return(-31);
412 }
413
414 /* If input padding is UNDEFINED ... */
415
1/2
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 21 taken 100 times.
100 if(ipad == UNDEFINED)
416 /* Use the padding specifically required by the rotated grids herein. */
417 rotgrids->pad = grid_pad;
418 else{
419 /* Otherwise, input pad was specified, so check to make sure it is */
420 /* sufficiently large to handle the rotated grids herein. */
421
1/2
✗ Branch 21 → 22 not taken.
✓ Branch 21 → 25 taken 100 times.
100 if(ipad < grid_pad){
422 /* If input pad is NOT large enough, then ERROR. */
423 fprintf(stderr, "ERROR : init_rotgrids : Pad passed is too small\n");
424 g_free(rotgrids);
425 return(-32);
426 }
427 /* Otherwise, use the specified input pad in computing grid offsets. */
428 100 rotgrids->pad = ipad;
429 }
430
431 /* Total number of points in grid */
432 100 grid_size = grid_w * grid_h;
433
434 /* Compute width of "padded" image */
435 100 pw = iw + (rotgrids->pad<<1);
436
437 /* Center coord of grid (0-oriented). */
438 100 cx = (grid_w-1)/(double)2.0;
439 100 cy = (grid_h-1)/(double)2.0;
440
441 /* Allocate list of rotgrid pointers */
442 100 rotgrids->grids = (int **)g_malloc(ndirs * sizeof(int *));
443
444 /* Pi_offset is the offset in radians from which angles are to begin. */
445 100 pi_offset = start_dir_angle;
446 100 pi_incr = M_PI/(double)ndirs; /* if ndirs == 16, incr = 11.25 degrees */
447
448 /* For each direction to rotate a grid ... */
449 100 for (dir = 0, theta = pi_offset;
450
2/2
✓ Branch 50 → 28 taken 1600 times.
✓ Branch 50 → 51 taken 100 times.
1700 dir < ndirs; dir++, theta += pi_incr) {
451
452 /* Allocate a rotgrid */
453 1600 rotgrids->grids[dir] = (int *)g_malloc(grid_size * sizeof(int));
454
455 /* Set pointer to current grid */
456 1600 grid = rotgrids->grids[dir];
457
458 /* Compute cos and sin of current angle */
459 1600 cs = cos(theta);
460 1600 sn = sin(theta);
461
462 /* This next section of nested FOR loops precomputes a */
463 /* rotated grid. The rotation is set up to rotate a GRID_W X */
464 /* GRID_H grid on its center point at C=(Cx,Cy). The current */
465 /* pixel being rotated is P=(Ix,Iy). Therefore, we have a */
466 /* rotation transformation of point P about pivot point C. */
467 /* The rotation transformation about a pivot point in matrix */
468 /* form is: */
469 /*
470 +- -+
471 | cos(T) sin(T) 0 |
472 [Ix Iy 1] | -sin(T) cos(T) 0 |
473 | (1-cos(T))*Cx + Cy*sin(T) (1-cos(T))*Cy - Cx*sin(T) 1 |
474 +- -+
475 */
476 /* Multiplying the 2 matrices and combining terms yeilds the */
477 /* equations for rotated coordinates (Rx, Ry): */
478 /* Rx = Cx + (Ix - Cx)*cos(T) - (Iy - Cy)*sin(T) */
479 /* Ry = Cy + (Ix - Cx)*sin(T) + (Iy - Cy)*cos(T) */
480 /* */
481 /* Care has been taken to ensure that (for example) when */
482 /* BLOCKSIZE==24 the rotated indices stay within a centered */
483 /* 34X34 area. */
484 /* This is important for computing an accurate padding of */
485 /* the input image. The rotation occurs "in-place" so that */
486 /* outer pixels in the grid are mapped at times from */
487 /* adjoining blocks. As a result, to keep from accessing */
488 /* "unknown" memory or pixels wrapped from the other side of */
489 /* the image, the input image should first be padded by */
490 /* PAD=round((DIAG - BLOCKSIZE)/2.0) where DIAG is the */
491 /* diagonal distance of the grid. */
492 /* For example, when BLOCKSIZE==24, Dx=34, so PAD=5. */
493
494 /* Foreach each y coord in block ... */
495
2/2
✓ Branch 48 → 30 taken 26400 times.
✓ Branch 48 → 49 taken 1600 times.
28000 for (iy = 0; iy < grid_h; ++iy) {
496 /* Compute rotation factors dependent on Iy (include constant) */
497 26400 fxm = -1.0 * ((iy - cy) * sn);
498 26400 fym = ((iy - cy) * cs);
499
500 /* If offsets are to be relative to the grids origin, then */
501 /* we need to subtract CX and CY. */
502
2/2
✓ Branch 30 → 31 taken 19200 times.
✓ Branch 30 → 32 taken 7200 times.
26400 if(relative2 == RELATIVE2ORIGIN){
503 19200 fxm += cx;
504 19200 fym += cy;
505 }
506
507 /* foreach each x coord in block ... */
508
2/2
✓ Branch 46 → 33 taken 511200 times.
✓ Branch 46 → 47 taken 26400 times.
537600 for (ix = 0; ix < grid_w; ++ix) {
509
510 /* Now combine factors dependent on Iy with those of Ix */
511 511200 fx = fxm + ((ix - cx) * cs);
512 511200 fy = fym + ((ix - cx) * sn);
513 /* Need to truncate precision so that answers are consistent */
514 /* on different computer architectures when rounding doubles. */
515
2/2
✓ Branch 33 → 34 taken 43150 times.
✓ Branch 33 → 35 taken 468050 times.
511200 fx = trunc_dbl_precision(fx, TRUNC_SCALE);
516
2/2
✓ Branch 36 → 37 taken 42600 times.
✓ Branch 36 → 38 taken 468600 times.
511200 fy = trunc_dbl_precision(fy, TRUNC_SCALE);
517
2/2
✓ Branch 39 → 40 taken 41350 times.
✓ Branch 39 → 41 taken 469850 times.
511200 ixt = sround(fx);
518
2/2
✓ Branch 42 → 43 taken 41350 times.
✓ Branch 42 → 44 taken 469850 times.
511200 iyt = sround(fy);
519
520 /* Store the current pixels relative */
521 /* rotated offset. Make sure to */
522 /* multiply the y-component of the */
523 /* offset by the "padded" image width! */
524 511200 *grid++ = ixt + (iyt * pw);
525 }/* ix */
526 }/* iy */
527 }/* dir */
528
529 100 *optr = rotgrids;
530 100 return(0);
531 }
532
533 /*************************************************************************
534 **************************************************************************
535 #cat: alloc_dir_powers - Allocates the memory associated with DFT power
536 #cat: vectors. The DFT analysis is conducted block by block in the
537 #cat: input image, and within each block, N wave forms are applied
538 #cat: at M different directions.
539
540 Input:
541 nwaves - number of DFT wave forms
542 ndirs - number of orientations (directions) used in DFT analysis
543 Output:
544 opowers - pointer to the allcated power vectors
545 Return Code:
546 Zero - successful completion
547 Negative - system error
548 **************************************************************************/
549 50 int alloc_dir_powers(double ***opowers, const int nwaves, const int ndirs)
550 {
551 50 int w;
552 50 double **powers;
553
554 /* Allocate list of double pointers to hold power vectors */
555 50 powers = (double **)g_malloc(nwaves * sizeof(double *));
556 /* Foreach DFT wave ... */
557
2/2
✓ Branch 6 → 4 taken 200 times.
✓ Branch 6 → 7 taken 50 times.
300 for(w = 0; w < nwaves; w++){
558 /* Allocate power vector for all directions */
559 200 powers[w] = (double *)g_malloc(ndirs * sizeof(double));
560 }
561
562 50 *opowers = powers;
563 50 return(0);
564 }
565
566 /*************************************************************************
567 **************************************************************************
568 #cat: alloc_power_stats - Allocates memory associated with set of statistics
569 #cat: derived from DFT power vectors computed in a block of the
570 #cat: input image. Statistics are not computed for the lowest DFT
571 #cat: wave form, so the length of the statistics arrays is 1 less
572 #cat: than the number of DFT wave forms used. The staistics
573 #cat: include the Maximum power for each wave form, the direction
574 #cat: at which the maximum power occured, and a normalized value
575 #cat: for the maximum power. In addition, the statistics are
576 #cat: ranked in descending order based on normalized squared
577 #cat: maximum power.
578
579 Input:
580 nstats - the number of waves forms from which statistics are to be
581 derived (N Waves - 1)
582 Output:
583 owis - points to an array to hold the ranked wave form indicies
584 of the corresponding statistics
585 opowmaxs - points to an array to hold the maximum DFT power for each
586 wave form
587 opowmax_dirs - points to an array to hold the direction corresponding to
588 each maximum power value
589 opownorms - points to an array to hold the normalized maximum power
590 Return Code:
591 Zero - successful completion
592 Negative - system error
593 **************************************************************************/
594 50 int alloc_power_stats(int **owis, double **opowmaxs, int **opowmax_dirs,
595 double **opownorms, const int nstats)
596 {
597 50 int *wis, *powmax_dirs;
598 50 double *powmaxs, *pownorms;
599
600
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 50 times.
50 ASSERT_SIZE_MUL(nstats, sizeof(int));
601
1/2
✓ Branch 4 → 5 taken 50 times.
✗ Branch 4 → 10 not taken.
50 ASSERT_SIZE_MUL(nstats, sizeof(double));
602
603 /* Allocate DFT wave index vector */
604 50 wis = (int *)g_malloc(nstats * sizeof(int));
605
606 /* Allocate max power vector */
607 50 powmaxs = (double *)g_malloc(nstats * sizeof(double));
608
609 /* Allocate max power direction vector */
610 50 powmax_dirs = (int *)g_malloc(nstats * sizeof(int));
611
612 /* Allocate normalized power vector */
613 50 pownorms = (double *)g_malloc(nstats * sizeof(double));
614
615 50 *owis = wis;
616 50 *opowmaxs = powmaxs;
617 50 *opowmax_dirs = powmax_dirs;
618 50 *opownorms = pownorms;
619 50 return(0);
620 }
621
622
623
624