File: | src/pull/volumePull.c |
Location: | line 379, column 36 |
Description: | Access to field 'shape' results in a dereference of a null pointer (loaded from variable 'gctx') |
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 | ||||
28 | pullVolume * | |||
29 | pullVolumeNew() { | |||
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 | ||||
59 | pullVolume * | |||
60 | pullVolumeNix(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 | */ | |||
89 | int | |||
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 )) { | |||
108 | biffAddf(PULLpullBiffKey, "%s: got NULL pointer", me); | |||
109 | return 1; | |||
110 | } | |||
111 | if (!ninSingle) { | |||
112 | biffAddf(PULLpullBiffKey, "%s: needed non-NULL ninSingle", me); | |||
113 | return 1; | |||
114 | } | |||
115 | if (!taskCopy) { | |||
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) { | |||
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); | |||
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, | |||
156 | ksp00->kernel, ksp00->parm); | |||
157 | if (!E) E |= gageKernelSet(vol->gctx, gageKernel11, | |||
158 | ksp11->kernel, ksp11->parm); | |||
159 | if (!E) E |= gageKernelSet(vol->gctx, gageKernel22, | |||
160 | ksp22->kernel, ksp22->parm); | |||
161 | if (ninScale) { | |||
162 | if (!kspSS) { | |||
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)); | |||
168 | vol->gpvlSS = AIR_CAST(gagePerVolume **,((gagePerVolume **)(calloc(ninNum, sizeof(gagePerVolume *)))) | |||
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 | */ | |||
233 | int | |||
234 | pullVolumeSingleAdd(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 | */ | |||
266 | int | |||
267 | pullVolumeStackAdd(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 | */ | |||
304 | pullVolume * | |||
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 | ||||
336 | int | |||
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 | */ | |||
352 | int | |||
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 | */ | |||
486 | unsigned 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 | ||||
512 | const pullVolume * | |||
513 | pullVolumeLookup(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 | */ | |||
532 | int | |||
533 | pullConstraintScaleRange(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 | } |