| 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 | } |