GCC Code Coverage Report


Directory: ./
File: libfprint/nbis/mindtct/init.c
Date: 2024-05-04 14:54:39
Exec Total Coverage
Lines: 139 147 94.6%
Functions: 6 6 100.0%
Branches: 42 55 76.4%

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 48 int init_dir2rad(DIR2RAD **optr, const int ndirs)
87 {
88 48 DIR2RAD *dir2rad;
89 48 int i;
90 48 double theta, pi_factor;
91 48 double cs, sn;
92
93 /* Allocate structure */
94 48 dir2rad = (DIR2RAD *)g_malloc(sizeof(DIR2RAD));
95
96 /* Assign number of directions */
97 48 dir2rad->ndirs = ndirs;
98
99 /* Allocate cosine vector */
100 48 dir2rad->cos = (double *)g_malloc(ndirs * sizeof(double));
101
102 /* Allocate sine vector */
103 48 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 48 pi_factor = 2.0*M_PI/(double)ndirs;
108
109 /* Now compute cos and sin values for each direction. */
110
2/2
✓ Branch 0 taken 768 times.
✓ Branch 1 taken 48 times.
816 for (i = 0; i < ndirs; ++i) {
111 768 theta = (double)(i * pi_factor);
112 768 cs = cos(theta);
113 768 sn = sin(theta);
114 /* Need to truncate precision so that answers are consistent */
115 /* on different computer architectures. */
116
2/2
✓ Branch 0 taken 384 times.
✓ Branch 1 taken 384 times.
768 cs = trunc_dbl_precision(cs, TRUNC_SCALE);
117
2/2
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 432 times.
768 sn = trunc_dbl_precision(sn, TRUNC_SCALE);
118 768 dir2rad->cos[i] = cs;
119 768 dir2rad->sin[i] = sn;
120 }
121
122 48 *optr = dir2rad;
123 48 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 48 int init_dftwaves(DFTWAVES **optr, const double *dft_coefs,
144 const int nwaves, const int blocksize)
145 {
146 48 DFTWAVES *dftwaves;
147 48 int i, j;
148 48 double pi_factor, freq, x;
149 48 double *cptr, *sptr;
150
151 /* Allocate structure */
152 48 dftwaves = (DFTWAVES *)g_malloc(sizeof(DFTWAVES));
153
154 /* Set number of DFT waves */
155 48 dftwaves->nwaves = nwaves;
156 /* Set wave length of the DFT waves (they all must be the same length) */
157 48 dftwaves->wavelen = blocksize;
158
159 /* Allocate list of wave pointers */
160 48 dftwaves->waves = (DFTWAVE **)g_malloc(nwaves * sizeof(DFTWAVE *));
161 48 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 48 pi_factor = 2.0*M_PI/(double)blocksize;
172
173 /* Foreach of 4 DFT frequency coef ... */
174
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 48 times.
240 for (i = 0; i < nwaves; ++i) {
175 /* Allocate wave structure */
176 192 dftwaves->waves[i] = (DFTWAVE *)g_malloc(sizeof(DFTWAVE));
177 /* Allocate cosine vector */
178 192 dftwaves->waves[i]->cos = (double *)g_malloc(blocksize * sizeof(double));
179 /* Allocate sine vector */
180 192 dftwaves->waves[i]->sin = (double *)g_malloc(blocksize * sizeof(double));
181
182 /* Assign pointer nicknames */
183 192 cptr = dftwaves->waves[i]->cos;
184 192 sptr = dftwaves->waves[i]->sin;
185
186 /* Compute actual frequency */
187 192 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 0 taken 4608 times.
✓ Branch 1 taken 192 times.
4800 for (j = 0; j < blocksize; ++j) {
191 /* Compute sample points from frequency */
192 4608 x = freq * (double)j;
193 /* Store cos and sin components of sample point */
194 4608 *cptr++ = cos(x);
195 4608 *sptr++ = sin(x);
196 }
197 }
198
199 48 *optr = dftwaves;
200 48 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 48 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 48 int dft_pad, dirbin_pad, max_pad;
258 48 double diag;
259 48 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 48 diag = sqrt((double)(2.0 * map_windowsize * map_windowsize));
306 48 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 0 not taken.
✓ Branch 1 taken 48 times.
48 pad = trunc_dbl_precision(pad, TRUNC_SCALE);
310 /* Must add the window offset to the rotational padding. */
311
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 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 48 diag = sqrt((double)((dirbin_grid_w*dirbin_grid_w)+
317 48 (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 48 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 0 not taken.
✓ Branch 1 taken 48 times.
48 pad = trunc_dbl_precision(pad, TRUNC_SCALE);
324
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 dirbin_pad = sround(pad);
325
326 48 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 48 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 96 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 96 ROTGRIDS *rotgrids;
366 96 double pi_offset, pi_incr;
367 96 int dir, ix, iy, grid_size, pw, grid_pad, min_dim;
368 96 int *grid;
369 96 double diag, theta, cs, sn, cx, cy;
370 96 double fxm, fym, fx, fy;
371 96 int ixt, iyt;
372 96 double pad;
373
374 /* Allocate structure */
375 96 rotgrids = (ROTGRIDS *)g_malloc(sizeof(ROTGRIDS));
376
377 /* Set rotgrid attributes */
378 96 rotgrids->ngrids = ndirs;
379 96 rotgrids->grid_w = grid_w;
380 96 rotgrids->grid_h = grid_h;
381 96 rotgrids->start_angle = start_dir_angle;
382 96 rotgrids->relative2 = relative2;
383
384 /* Compute pad based on diagonal of the grid */
385 96 diag = sqrt((double)((grid_w*grid_w)+(grid_h*grid_h)));
386
2/3
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
96 switch(relative2){
387 48 case RELATIVE2CENTER:
388 /* Assumption: all grid centers reside in valid/allocated memory. */
389 48 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 0 not taken.
✓ Branch 1 taken 48 times.
48 pad = trunc_dbl_precision(pad, TRUNC_SCALE);
393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 grid_pad = sround(pad);
394 break;
395 48 case RELATIVE2ORIGIN:
396 /* Assumption: all grid origins reside in valid/allocated memory. */
397 48 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 48 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 0 not taken.
✓ Branch 1 taken 48 times.
48 pad = trunc_dbl_precision(pad, TRUNC_SCALE);
404
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 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 0 not taken.
✓ Branch 1 taken 96 times.
96 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 0 not taken.
✓ Branch 1 taken 96 times.
96 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 96 rotgrids->pad = ipad;
429 }
430
431 /* Total number of points in grid */
432 96 grid_size = grid_w * grid_h;
433
434 /* Compute width of "padded" image */
435 96 pw = iw + (rotgrids->pad<<1);
436
437 /* Center coord of grid (0-oriented). */
438 96 cx = (grid_w-1)/(double)2.0;
439 96 cy = (grid_h-1)/(double)2.0;
440
441 /* Allocate list of rotgrid pointers */
442 96 rotgrids->grids = (int **)g_malloc(ndirs * sizeof(int *));
443
444 /* Pi_offset is the offset in radians from which angles are to begin. */
445 96 pi_offset = start_dir_angle;
446 96 pi_incr = M_PI/(double)ndirs; /* if ndirs == 16, incr = 11.25 degrees */
447
448 /* For each direction to rotate a grid ... */
449 96 for (dir = 0, theta = pi_offset;
450
2/2
✓ Branch 0 taken 1536 times.
✓ Branch 1 taken 96 times.
1632 dir < ndirs; dir++, theta += pi_incr) {
451
452 /* Allocate a rotgrid */
453 1536 rotgrids->grids[dir] = (int *)g_malloc(grid_size * sizeof(int));
454
455 /* Set pointer to current grid */
456 1536 grid = rotgrids->grids[dir];
457
458 /* Compute cos and sin of current angle */
459 1536 cs = cos(theta);
460 1536 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 0 taken 25344 times.
✓ Branch 1 taken 1536 times.
26880 for (iy = 0; iy < grid_h; ++iy) {
496 /* Compute rotation factors dependent on Iy (include constant) */
497 25344 fxm = -1.0 * ((iy - cy) * sn);
498 25344 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 0 taken 18432 times.
✓ Branch 1 taken 6912 times.
25344 if(relative2 == RELATIVE2ORIGIN){
503 18432 fxm += cx;
504 18432 fym += cy;
505 }
506
507 /* foreach each x coord in block ... */
508
2/2
✓ Branch 0 taken 490752 times.
✓ Branch 1 taken 25344 times.
516096 for (ix = 0; ix < grid_w; ++ix) {
509
510 /* Now combine factors dependent on Iy with those of Ix */
511 490752 fx = fxm + ((ix - cx) * cs);
512 490752 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 0 taken 41424 times.
✓ Branch 1 taken 449328 times.
490752 fx = trunc_dbl_precision(fx, TRUNC_SCALE);
516
2/2
✓ Branch 0 taken 40896 times.
✓ Branch 1 taken 449856 times.
490752 fy = trunc_dbl_precision(fy, TRUNC_SCALE);
517
2/2
✓ Branch 0 taken 39696 times.
✓ Branch 1 taken 451056 times.
490752 ixt = sround(fx);
518
2/2
✓ Branch 0 taken 39696 times.
✓ Branch 1 taken 451056 times.
490752 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 490752 *grid++ = ixt + (iyt * pw);
525 }/* ix */
526 }/* iy */
527 }/* dir */
528
529 96 *optr = rotgrids;
530 96 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 48 int alloc_dir_powers(double ***opowers, const int nwaves, const int ndirs)
550 {
551 48 int w;
552 48 double **powers;
553
554 /* Allocate list of double pointers to hold power vectors */
555 48 powers = (double **)g_malloc(nwaves * sizeof(double *));
556 /* Foreach DFT wave ... */
557
2/2
✓ Branch 1 taken 192 times.
✓ Branch 2 taken 48 times.
288 for(w = 0; w < nwaves; w++){
558 /* Allocate power vector for all directions */
559 192 powers[w] = (double *)g_malloc(ndirs * sizeof(double));
560 }
561
562 48 *opowers = powers;
563 48 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 48 int alloc_power_stats(int **owis, double **opowmaxs, int **opowmax_dirs,
595 double **opownorms, const int nstats)
596 {
597 48 int *wis, *powmax_dirs;
598 48 double *powmaxs, *pownorms;
599
600
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
48 ASSERT_SIZE_MUL(nstats, sizeof(int));
601
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 ASSERT_SIZE_MUL(nstats, sizeof(double));
602
603 /* Allocate DFT wave index vector */
604 48 wis = (int *)g_malloc(nstats * sizeof(int));
605
606 /* Allocate max power vector */
607 48 powmaxs = (double *)g_malloc(nstats * sizeof(double));
608
609 /* Allocate max power direction vector */
610 48 powmax_dirs = (int *)g_malloc(nstats * sizeof(int));
611
612 /* Allocate normalized power vector */
613 48 pownorms = (double *)g_malloc(nstats * sizeof(double));
614
615 48 *owis = wis;
616 48 *opowmaxs = powmaxs;
617 48 *opowmax_dirs = powmax_dirs;
618 48 *opownorms = pownorms;
619 48 return(0);
620 }
621
622
623
624