Bug Summary

File:src/pull/volumePull.c
Location:line 168, column 19
Description:Call to 'calloc' has an allocation size of 0 bytes

Annotated Source Code

1/*
2 Teem: Tools to process and visualize scientific data and images .
3 Copyright (C) 2013, 2012, 2011, 2010, 2009 University of Chicago
4 Copyright (C) 2008, 2007, 2006, 2005 Gordon Kindlmann
5 Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998 University of Utah
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public License
9 (LGPL) as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11 The terms of redistributing and/or modifying this software also
12 include exceptions to the LGPL that facilitate static linking.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with this library; if not, write to Free Software Foundation, Inc.,
21 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22*/
23
24
25#include "pull.h"
26#include "privatePull.h"
27
28pullVolume *
29pullVolumeNew() {
30 pullVolume *vol;
31
32 vol = AIR_CAST(pullVolume *, calloc(1, sizeof(pullVolume)))((pullVolume *)(calloc(1, sizeof(pullVolume))));
33 if (vol) {
34 vol->verbose = 0;
35 vol->name = NULL((void*)0);
36 vol->kind = NULL((void*)0);
37 vol->ninSingle = NULL((void*)0);
38 vol->ninScale = NULL((void*)0);
39 vol->scaleNum = 0;
40 vol->scalePos = NULL((void*)0);
41 vol->scaleDerivNorm = AIR_FALSE0;
42 vol->scaleDerivNormBias = 0.0;
43 vol->ksp00 = nrrdKernelSpecNew();
44 vol->ksp11 = nrrdKernelSpecNew();
45 vol->ksp22 = nrrdKernelSpecNew();
46 vol->kspSS = nrrdKernelSpecNew();
47 GAGE_QUERY_RESET(vol->pullValQuery)vol->pullValQuery[ 0] = vol->pullValQuery[ 1] = vol->
pullValQuery[ 2] = vol->pullValQuery[ 3] = vol->pullValQuery
[ 4] = vol->pullValQuery[ 5] = vol->pullValQuery[ 6] = vol
->pullValQuery[ 7] = vol->pullValQuery[ 8] = vol->pullValQuery
[ 9] = vol->pullValQuery[10] = vol->pullValQuery[11] = vol
->pullValQuery[12] = vol->pullValQuery[13] = vol->pullValQuery
[14] = vol->pullValQuery[15] = vol->pullValQuery[16] = vol
->pullValQuery[17] = vol->pullValQuery[18] = vol->pullValQuery
[19] = vol->pullValQuery[20] = vol->pullValQuery[21] = vol
->pullValQuery[22] = vol->pullValQuery[23] = vol->pullValQuery
[24] = vol->pullValQuery[25] = vol->pullValQuery[26] = vol
->pullValQuery[27] = vol->pullValQuery[28] = vol->pullValQuery
[29] = vol->pullValQuery[30] = vol->pullValQuery[31] = 0
;
48 vol->gctx = NULL((void*)0);
49 vol->gpvl = NULL((void*)0);
50 vol->gpvlSS = NULL((void*)0);
51 /* this is turned OFF in volumes that have infos that aren't seedthresh,
52 see pullInfoSpecAdd() */
53 vol->seedOnly = AIR_TRUE1;
54 vol->forSeedPreThresh = AIR_FALSE0;
55 }
56 return vol;
57}
58
59pullVolume *
60pullVolumeNix(pullVolume *vol) {
61
62 if (vol) {
63 airFree(vol->name);
64 airFree(vol->scalePos);
65 vol->ksp00 = nrrdKernelSpecNix(vol->ksp00);
66 vol->ksp11 = nrrdKernelSpecNix(vol->ksp11);
67 vol->ksp22 = nrrdKernelSpecNix(vol->ksp22);
68 vol->kspSS = nrrdKernelSpecNix(vol->kspSS);
69 if (vol->gctx) {
70 vol->gctx = gageContextNix(vol->gctx);
71 }
72 airFree(vol->gpvlSS);
73 airFree(vol);
74 }
75 return NULL((void*)0);
76}
77
78/*
79** used to set all the fields of pullVolume at once, including the
80** gageContext inside the pullVolume
81**
82** OLD description ...
83** used both for top-level volumes in the pullContext (pctx->vol[i])
84** in which case pctx is non-NULL,
85** and for the per-task volumes (task->vol[i]),
86** in which case pctx is NULL
87** ...................
88*/
89int
90_pullVolumeSet(const pullContext *pctx, int taskCopy, pullVolume *vol,
91 const gageKind *kind,
92 int verbose, const char *name,
93 const Nrrd *ninSingle,
94 const Nrrd *const *ninScale,
95 double *scalePos,
96 unsigned int ninNum,
97 int scaleDerivNorm,
98 double scaleDerivNormBias,
99 const NrrdKernelSpec *ksp00,
100 const NrrdKernelSpec *ksp11,
101 const NrrdKernelSpec *ksp22,
102 const NrrdKernelSpec *kspSS) {
103 static const char me[]="_pullVolumeSet";
104 int E;
105 unsigned int vi;
106
107 if (!( vol && kind && airStrlen(name) && ksp00 && ksp11 && ksp22 )) {
1
Taking false branch
108 biffAddf(PULLpullBiffKey, "%s: got NULL pointer", me);
109 return 1;
110 }
111 if (!ninSingle) {
2
Assuming 'ninSingle' is non-null
3
Taking false branch
112 biffAddf(PULLpullBiffKey, "%s: needed non-NULL ninSingle", me);
113 return 1;
114 }
115 if (!taskCopy) {
4
Assuming 'taskCopy' is not equal to 0
5
Taking false branch
116 for (vi=0; vi<pctx->volNum; vi++) {
117 if (pctx->vol[vi] == vol) {
118 biffAddf(PULLpullBiffKey, "%s: already got vol %p as vol[%u]", me,
119 AIR_VOIDP(vol)((void *)(vol)), vi);
120 return 1;
121 }
122 }
123 }
124 if (ninNum) {
6
Assuming 'ninNum' is 0
7
Taking false branch
125 if (!( ninNum >= 2 )) {
126 biffAddf(PULLpullBiffKey, "%s: need at least 2 volumes (not %u)", me, ninNum);
127 return 1;
128 }
129 if (!scalePos) {
130 biffAddf(PULLpullBiffKey, "%s: need non-NULL scalePos with ninNum %u", me, ninNum);
131 return 1;
132 }
133 if (!ninScale) {
134 biffAddf(PULLpullBiffKey, "%s: need non-NULL ninScale with ninNum %u", me, ninNum);
135 return 1;
136 }
137 }
138
139 vol->verbose = verbose;
140 vol->kind = kind;
141 vol->gctx = gageContextNew();
142 gageParmSet(vol->gctx, gageParmVerbose,
143 vol->verbose > 0 ? vol->verbose - 1 : 0);
8
'?' condition is false
144 gageParmSet(vol->gctx, gageParmRenormalize, AIR_FALSE0);
145 /* because we're likely only using accurate kernels */
146 gageParmSet(vol->gctx, gageParmStackNormalizeRecon, AIR_FALSE0);
147 vol->scaleDerivNorm = scaleDerivNorm;
148 gageParmSet(vol->gctx, gageParmStackNormalizeDeriv, scaleDerivNorm);
149 vol->scaleDerivNormBias = scaleDerivNormBias;
150 gageParmSet(vol->gctx, gageParmStackNormalizeDerivBias,
151 scaleDerivNormBias);
152 gageParmSet(vol->gctx, gageParmTwoDimZeroZ, pctx->flag.zeroZ);
153 gageParmSet(vol->gctx, gageParmCheckIntegrals, AIR_TRUE1);
154 E = 0;
155 if (!E) E |= gageKernelSet(vol->gctx, gageKernel00,
9
Taking true branch
156 ksp00->kernel, ksp00->parm);
157 if (!E) E |= gageKernelSet(vol->gctx, gageKernel11,
10
Assuming 'E' is not equal to 0
11
Taking false branch
158 ksp11->kernel, ksp11->parm);
159 if (!E) E |= gageKernelSet(vol->gctx, gageKernel22,
12
Taking false branch
160 ksp22->kernel, ksp22->parm);
161 if (ninScale) {
13
Assuming 'ninScale' is non-null
14
Taking true branch
162 if (!kspSS) {
15
Assuming 'kspSS' is non-null
16
Taking false branch
163 biffAddf(PULLpullBiffKey, "%s: got NULL kspSS", me);
164 return 1;
165 }
166 gageParmSet(vol->gctx, gageParmStackUse, AIR_TRUE1);
167 if (!E) E |= !(vol->gpvl = gagePerVolumeNew(vol->gctx, ninSingle, kind));
17
Taking false branch
168 vol->gpvlSS = AIR_CAST(gagePerVolume **,((gagePerVolume **)(calloc(ninNum, sizeof(gagePerVolume *))))
18
Within the expansion of the macro 'AIR_CAST':
a
Call to 'calloc' has an allocation size of 0 bytes
169 calloc(ninNum, sizeof(gagePerVolume *)))((gagePerVolume **)(calloc(ninNum, sizeof(gagePerVolume *))));
170 if (!E) E |= gageStackPerVolumeNew(vol->gctx, vol->gpvlSS,
171 ninScale, ninNum, kind);
172 if (!E) E |= gageStackPerVolumeAttach(vol->gctx, vol->gpvl, vol->gpvlSS,
173 scalePos, ninNum);
174 if (!E) E |= gageKernelSet(vol->gctx, gageKernelStack,
175 kspSS->kernel, kspSS->parm);
176 } else {
177 vol->gpvlSS = NULL((void*)0);
178 if (!E) E |= !(vol->gpvl = gagePerVolumeNew(vol->gctx, ninSingle, kind));
179 if (!E) E |= gagePerVolumeAttach(vol->gctx, vol->gpvl);
180 }
181 if (E) {
182 biffMovef(PULLpullBiffKey, GAGEgageBiffKey, "%s: trouble (%s %s)", me,
183 ninSingle ? "ninSingle" : "",
184 ninScale ? "ninScale" : "");
185 return 1;
186 }
187 gageQueryReset(vol->gctx, vol->gpvl);
188 /* the query is the single thing remaining unset in the gageContext */
189
190 vol->name = airStrdup(name);
191 if (!vol->name) {
192 biffAddf(PULLpullBiffKey, "%s: couldn't strdup name (len %u)", me,
193 AIR_CAST(unsigned int, airStrlen(name))((unsigned int)(airStrlen(name))));
194 return 1;
195 }
196 if (vol->verbose) {
197 printf("%s: ---- vol=%p, name = %p = |%s|\n", me, AIR_VOIDP(vol)((void *)(vol)),
198 AIR_VOIDP(vol->name)((void *)(vol->name)), vol->name);
199 if (0 != vol->scaleDerivNormBias) {
200 printf("%s: ---- scale deriv norm bias = %g\n", me,
201 vol->scaleDerivNormBias);
202 }
203 }
204 nrrdKernelSpecSet(vol->ksp00, ksp00->kernel, ksp00->parm);
205 nrrdKernelSpecSet(vol->ksp11, ksp11->kernel, ksp11->parm);
206 nrrdKernelSpecSet(vol->ksp22, ksp22->kernel, ksp22->parm);
207 if (ninScale) {
208 vol->ninSingle = ninSingle;
209 vol->ninScale = ninScale;
210 vol->scaleNum = ninNum;
211 vol->scalePos = AIR_CAST(double *, calloc(ninNum, sizeof(double)))((double *)(calloc(ninNum, sizeof(double))));
212 if (!vol->scalePos) {
213 biffAddf(PULLpullBiffKey, "%s: couldn't calloc scalePos", me);
214 return 1;
215 }
216 for (vi=0; vi<ninNum; vi++) {
217 vol->scalePos[vi] = scalePos[vi];
218 }
219 nrrdKernelSpecSet(vol->kspSS, kspSS->kernel, kspSS->parm);
220 } else {
221 vol->ninSingle = ninSingle;
222 vol->ninScale = NULL((void*)0);
223 vol->scaleNum = 0;
224 /* leave kspSS as is (unset) */
225 }
226
227 return 0;
228}
229
230/*
231** the effect is to give pctx ownership of the vol
232*/
233int
234pullVolumeSingleAdd(pullContext *pctx,
235 const gageKind *kind,
236 char *name, const Nrrd *nin,
237 const NrrdKernelSpec *ksp00,
238 const NrrdKernelSpec *ksp11,
239 const NrrdKernelSpec *ksp22) {
240 static const char me[]="pullVolumeSingleSet";
241 pullVolume *vol;
242
243 vol = pullVolumeNew();
244 if (_pullVolumeSet(pctx, AIR_FALSE0 /* taskCopy */, vol, kind,
245 pctx->verbose, name,
246 nin,
247 NULL((void*)0), NULL((void*)0), 0, AIR_FALSE0, 0.0,
248 ksp00, ksp11, ksp22, NULL((void*)0))) {
249 biffAddf(PULLpullBiffKey, "%s: trouble", me);
250 return 1;
251 }
252
253 /* add this volume to context */
254 if (pctx->verbose) {
255 printf("%s: adding pctx->vol[%u] = %p\n", me, pctx->volNum,
256 AIR_VOIDP(vol)((void *)(vol)));
257 }
258 pctx->vol[pctx->volNum] = vol;
259 pctx->volNum++;
260 return 0;
261}
262
263/*
264** the effect is to give pctx ownership of the vol
265*/
266int
267pullVolumeStackAdd(pullContext *pctx,
268 const gageKind *kind,
269 char *name,
270 const Nrrd *nin,
271 const Nrrd *const *ninSS,
272 double *scalePos,
273 unsigned int ninNum,
274 int scaleDerivNorm,
275 double scaleDerivNormBias,
276 const NrrdKernelSpec *ksp00,
277 const NrrdKernelSpec *ksp11,
278 const NrrdKernelSpec *ksp22,
279 const NrrdKernelSpec *kspSS) {
280 static const char me[]="pullVolumeStackAdd";
281 pullVolume *vol;
282
283 vol = pullVolumeNew();
284 if (_pullVolumeSet(pctx, AIR_FALSE0 /* taskCopy */, vol, kind,
285 pctx->verbose, name,
286 nin,
287 ninSS, scalePos, ninNum,
288 scaleDerivNorm, scaleDerivNormBias,
289 ksp00, ksp11, ksp22, kspSS)) {
290 biffAddf(PULLpullBiffKey, "%s: trouble", me);
291 return 1;
292 }
293
294 /* add this volume to context */
295 pctx->vol[pctx->volNum++] = vol;
296 return 0;
297}
298
299/*
300** this is only used to create pullVolumes for the pullTasks
301**
302** DOES use biff
303*/
304pullVolume *
305_pullVolumeCopy(const pullContext *pctx, const pullVolume *volOrig) {
306 static const char me[]="pullVolumeCopy";
307 pullVolume *volNew;
308
309 volNew = pullVolumeNew();
310 if (_pullVolumeSet(pctx, AIR_TRUE1 /* taskCopy */, volNew, volOrig->kind,
311 volOrig->verbose, volOrig->name,
312 volOrig->ninSingle,
313 volOrig->ninScale,
314 volOrig->scalePos,
315 volOrig->scaleNum,
316 volOrig->scaleDerivNorm,
317 volOrig->scaleDerivNormBias,
318 volOrig->ksp00, volOrig->ksp11,
319 volOrig->ksp22, volOrig->kspSS)) {
320 biffAddf(PULLpullBiffKey, "%s: trouble creating new volume", me);
321 return NULL((void*)0);
322 }
323 volNew->seedOnly = volOrig->seedOnly;
324 volNew->forSeedPreThresh = volOrig->forSeedPreThresh;
325 /* _pullVolumeSet just created a new (per-task) gageContext, and
326 it will not learn the items from the info specs, so we have to
327 add query here */
328 if (gageQuerySet(volNew->gctx, volNew->gpvl, volOrig->gpvl->query)
329 || gageUpdate(volNew->gctx)) {
330 biffMovef(PULLpullBiffKey, GAGEgageBiffKey, "%s: trouble with new volume gctx", me);
331 return NULL((void*)0);
332 }
333 return volNew;
334}
335
336int
337_pullInsideBBox(pullContext *pctx, double pos[4]) {
338
339 return (AIR_IN_CL(pctx->bboxMin[0], pos[0], pctx->bboxMax[0])((pctx->bboxMin[0]) <= (pos[0]) && (pos[0]) <=
(pctx->bboxMax[0]))
&&
340 AIR_IN_CL(pctx->bboxMin[1], pos[1], pctx->bboxMax[1])((pctx->bboxMin[1]) <= (pos[1]) && (pos[1]) <=
(pctx->bboxMax[1]))
&&
341 AIR_IN_CL(pctx->bboxMin[2], pos[2], pctx->bboxMax[2])((pctx->bboxMin[2]) <= (pos[2]) && (pos[2]) <=
(pctx->bboxMax[2]))
&&
342 AIR_IN_CL(pctx->bboxMin[3], pos[3], pctx->bboxMax[3])((pctx->bboxMin[3]) <= (pos[3]) && (pos[3]) <=
(pctx->bboxMax[3]))
);
343}
344
345/*
346** sets:
347** pctx->haveScale
348** pctx->voxelSizeSpace, voxelSizeScale
349** pctx->bboxMin ([0] through [3], always)
350** pctx->bboxMax (same)
351*/
352int
353_pullVolumeSetup(pullContext *pctx) {
354 static const char me[]="_pullVolumeSetup";
355 unsigned int ii, numScale;
356
357 /* first see if there are any gage problems */
358 for (ii=0; ii<pctx->volNum; ii++) {
359 if (pctx->verbose) {
360 printf("%s: gageUpdate(vol[%u])\n", me, ii);
361 }
362 if (pctx->vol[ii]->gctx) {
363 if (gageUpdate(pctx->vol[ii]->gctx)) {
364 biffMovef(PULLpullBiffKey, GAGEgageBiffKey, "%s: trouble setting up gage on vol "
365 "%u/%u (\"%s\")", me, ii, pctx->volNum,
366 pctx->vol[ii]->name);
367 return 1;
368 }
369 } else {
370 biffAddf(PULLpullBiffKey, "%s: vol[%u] has NULL gctx", me, ii);
371 }
372 }
373
374 pctx->voxelSizeSpace = 0.0;
375 for (ii=0; ii<pctx->volNum; ii++) {
376 double min[3], max[3];
377 gageContext *gctx;
378 gctx = pctx->vol[ii]->gctx;
379 gageShapeBoundingBox(min, max, gctx->shape);
380 if (!ii) {
381 ELL_3V_COPY(pctx->bboxMin, min)((pctx->bboxMin)[0] = (min)[0], (pctx->bboxMin)[1] = (min
)[1], (pctx->bboxMin)[2] = (min)[2])
;
382 ELL_3V_COPY(pctx->bboxMax, max)((pctx->bboxMax)[0] = (max)[0], (pctx->bboxMax)[1] = (max
)[1], (pctx->bboxMax)[2] = (max)[2])
;
383 } else {
384 ELL_3V_MIN(pctx->bboxMin, pctx->bboxMin, min)( (pctx->bboxMin)[0] = (((pctx->bboxMin)[0]) < ((min
)[0]) ? ((pctx->bboxMin)[0]) : ((min)[0])), (pctx->bboxMin
)[1] = (((pctx->bboxMin)[1]) < ((min)[1]) ? ((pctx->
bboxMin)[1]) : ((min)[1])), (pctx->bboxMin)[2] = (((pctx->
bboxMin)[2]) < ((min)[2]) ? ((pctx->bboxMin)[2]) : ((min
)[2])))
;
385 ELL_3V_MIN(pctx->bboxMax, pctx->bboxMax, max)( (pctx->bboxMax)[0] = (((pctx->bboxMax)[0]) < ((max
)[0]) ? ((pctx->bboxMax)[0]) : ((max)[0])), (pctx->bboxMax
)[1] = (((pctx->bboxMax)[1]) < ((max)[1]) ? ((pctx->
bboxMax)[1]) : ((max)[1])), (pctx->bboxMax)[2] = (((pctx->
bboxMax)[2]) < ((max)[2]) ? ((pctx->bboxMax)[2]) : ((max
)[2])))
;
386 }
387 pctx->voxelSizeSpace += ELL_3V_LEN(gctx->shape->spacing)(sqrt((((gctx->shape->spacing))[0]*((gctx->shape->
spacing))[0] + ((gctx->shape->spacing))[1]*((gctx->shape
->spacing))[1] + ((gctx->shape->spacing))[2]*((gctx->
shape->spacing))[2])))
/sqrt(3.0);
388 if (ii && !pctx->initParm.unequalShapesAllow) {
389 if (!gageShapeEqual(pctx->vol[0]->gctx->shape, pctx->vol[0]->name,
390 pctx->vol[ii]->gctx->shape, pctx->vol[ii]->name)) {
391 biffMovef(PULLpullBiffKey, GAGEgageBiffKey,
392 "%s: need equal shapes, but vol 0 and %u different",
393 me, ii);
394 return 1;
395 }
396 }
397 }
398 pctx->voxelSizeSpace /= pctx->volNum;
399 /* have now computed bbox{Min,Max}[0,1,2]; now do bbox{Min,Max}[3] */
400 pctx->bboxMin[3] = pctx->bboxMax[3] = 0.0;
401 pctx->haveScale = AIR_FALSE0;
402 pctx->voxelSizeScale = 0.0;
403 numScale = 0;
404 for (ii=0; ii<pctx->volNum; ii++) {
405 if (pctx->vol[ii]->ninScale) {
406 double sclMin, sclMax, sclStep;
407 unsigned int si;
408 numScale ++;
409 sclMin = pctx->vol[ii]->scalePos[0];
410 if (pctx->flag.scaleIsTau) {
411 sclMin = gageTauOfSig(sclMin)airTauOfSigma(sclMin);
412 }
413 sclMax = pctx->vol[ii]->scalePos[pctx->vol[ii]->scaleNum-1];
414 if (pctx->flag.scaleIsTau) {
415 sclMax = gageTauOfSig(sclMax)airTauOfSigma(sclMax);
416 }
417 sclStep = 0;
418 for (si=0; si<pctx->vol[ii]->scaleNum-1; si++) {
419 double scl0, scl1;
420 scl1 = pctx->vol[ii]->scalePos[si+1];
421 scl0 = pctx->vol[ii]->scalePos[si];
422 if (pctx->flag.scaleIsTau) {
423 scl1 = gageTauOfSig(scl1)airTauOfSigma(scl1);
424 scl0 = gageTauOfSig(scl0)airTauOfSigma(scl0);
425 }
426 sclStep += (scl1 - scl0);
427 }
428 sclStep /= pctx->vol[ii]->scaleNum-1;
429 pctx->voxelSizeScale += sclStep;
430 if (!pctx->haveScale) {
431 pctx->bboxMin[3] = sclMin;
432 pctx->bboxMax[3] = sclMax;
433 pctx->haveScale = AIR_TRUE1;
434 } else {
435 /* we already know haveScale; expand existing range */
436 pctx->bboxMin[3] = AIR_MIN(sclMin, pctx->bboxMin[3])((sclMin) < (pctx->bboxMin[3]) ? (sclMin) : (pctx->bboxMin
[3]))
;
437 pctx->bboxMax[3] = AIR_MAX(sclMax, pctx->bboxMax[3])((sclMax) > (pctx->bboxMax[3]) ? (sclMax) : (pctx->bboxMax
[3]))
;
438 }
439 }
440 }
441 if (numScale) {
442 pctx->voxelSizeScale /= numScale;
443 }
444 if (pctx->verbose) {
445 printf("%s: bboxMin (%g,%g,%g,%g) max (%g,%g,%g,%g)\n", me,
446 pctx->bboxMin[0], pctx->bboxMin[1],
447 pctx->bboxMin[2], pctx->bboxMin[3],
448 pctx->bboxMax[0], pctx->bboxMax[1],
449 pctx->bboxMax[2], pctx->bboxMax[3]);
450 printf("%s: voxelSizeSpace %g Scale %g\n", me,
451 pctx->voxelSizeSpace, pctx->voxelSizeScale);
452 }
453
454 /* _energyInterParticle() depends on this error checking */
455 if (pctx->haveScale) {
456 if (pullInterTypeJustR == pctx->interType) {
457 biffAddf(PULLpullBiffKey, "%s: need scale-aware intertype (not %s) with "
458 "a scale-space volume",
459 me, airEnumStr(pullInterType, pullInterTypeJustR));
460 return 1;
461 }
462 } else {
463 /* don't have scale */
464 if (pullInterTypeJustR != pctx->interType) {
465 biffAddf(PULLpullBiffKey, "%s: can't use scale-aware intertype (%s) without "
466 "a scale-space volume",
467 me, airEnumStr(pullInterType, pctx->interType));
468 return 1;
469 }
470 }
471 if (pctx->flag.energyFromStrength
472 && !(pctx->ispec[pullInfoStrength] && pctx->haveScale)) {
473 biffAddf(PULLpullBiffKey, "%s: sorry, can use energyFromStrength only with both "
474 "a scale-space volume, and a strength info", me);
475 return 1;
476 }
477
478 return 0;
479}
480
481/*
482** basis of pullVolumeLookup
483**
484** uses biff, returns UINT_MAX in case of error
485*/
486unsigned int
487_pullVolumeIndex(const pullContext *pctx,
488 const char *volName) {
489 static const char me[]="_pullVolumeIndex";
490 unsigned int vi;
491
492 if (!( pctx && volName )) {
493 biffAddf(PULLpullBiffKey, "%s: got NULL pointer", me);
494 return UINT_MAX(2147483647 *2U +1U);
495 }
496 if (0 == pctx->volNum) {
497 biffAddf(PULLpullBiffKey, "%s: given context has no volumes", me);
498 return UINT_MAX(2147483647 *2U +1U);
499 }
500 for (vi=0; vi<pctx->volNum; vi++) {
501 if (!strcmp(pctx->vol[vi]->name, volName)) {
502 break;
503 }
504 }
505 if (vi == pctx->volNum) {
506 biffAddf(PULLpullBiffKey, "%s: no volume has name \"%s\"", me, volName);
507 return UINT_MAX(2147483647 *2U +1U);
508 }
509 return vi;
510}
511
512const pullVolume *
513pullVolumeLookup(const pullContext *pctx,
514 const char *volName) {
515 static const char me[]="pullVolumeLookup";
516 unsigned int vi;
517
518 vi = _pullVolumeIndex(pctx, volName);
519 if (UINT_MAX(2147483647 *2U +1U) == vi) {
520 biffAddf(PULLpullBiffKey, "%s: trouble looking up \"%s\"", me, volName);
521 return NULL((void*)0);
522 }
523 return pctx->vol[vi];
524}
525
526/*
527******** pullConstraintScaleRange
528**
529** returns scale range from a scale-space volume,
530** either in terms of sigma, or (if pctx->flag.scaleIsTau), tau
531*/
532int
533pullConstraintScaleRange(pullContext *pctx, double ssrange[2]) {
534 static const char me[]="pullConstraintScaleRange";
535 pullVolume *cvol;
536
537 if (!(pctx && ssrange)) {
538 biffAddf(PULLpullBiffKey, "%s: got NULL pointer", me);
539 return 1;
540 }
541 if (!(pctx->constraint)) {
542 biffAddf(PULLpullBiffKey, "%s: given context doesn't have constraint set", me);
543 return 1;
544 }
545 if (!(pctx->ispec[pctx->constraint])) {
546 biffAddf(PULLpullBiffKey, "%s: info %s not set for constriant", me,
547 airEnumStr(pullInfo, pctx->constraint));
548 return 1;
549 }
550 cvol = pctx->vol[pctx->ispec[pctx->constraint]->volIdx];
551 if (!cvol->ninScale) {
552 biffAddf(PULLpullBiffKey, "%s: volume \"%s\" has constraint but no scale-space",
553 me, cvol->name);
554 return 1;
555 }
556 ssrange[0] = cvol->scalePos[0];
557 ssrange[1] = cvol->scalePos[cvol->scaleNum-1];
558 if (pctx->flag.scaleIsTau) {
559 ssrange[0] = gageTauOfSig(ssrange[0])airTauOfSigma(ssrange[0]);
560 ssrange[1] = gageTauOfSig(ssrange[1])airTauOfSigma(ssrange[1]);
561 }
562
563 return 0;
564}