File: | src/pull/volumePull.c |
Location: | line 168, column 19 |
Description: | Call to 'calloc' has an allocation size of 0 bytes |
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 | } |