Bug Summary

File:src/nrrd/methodsNrrd.c
Location:line 415, column 3
Description:Value stored to 'ksp' is never read

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#include "nrrd.h"
25#include "privateNrrd.h"
26
27/*
28Wed Sep 14 05:55:40 EDT 2005: these are no longer used
29void
30nrrdPeripheralInit(Nrrd *nrrd) {
31
32 nrrdBasicInfoInit(nrrd,
33 NRRD_BASIC_INFO_DATA_BIT
34 | NRRD_BASIC_INFO_TYPE_BIT
35 | NRRD_BASIC_INFO_BLOCKSIZE_BIT
36 | NRRD_BASIC_INFO_DIMENSION_BIT
37 | NRRD_BASIC_INFO_CONTENT_BIT
38 | NRRD_BASIC_INFO_COMMENTS_BIT
39 | NRRD_BASIC_INFO_KEYVALUEPAIRS_BIT);
40 return;
41}
42
43int
44nrrdPeripheralCopy(Nrrd *nout, const Nrrd *nin) {
45
46 nrrdBasicInfoCopy(nout, nin,
47 NRRD_BASIC_INFO_DATA_BIT
48 | NRRD_BASIC_INFO_TYPE_BIT
49 | NRRD_BASIC_INFO_BLOCKSIZE_BIT
50 | NRRD_BASIC_INFO_DIMENSION_BIT
51 | NRRD_BASIC_INFO_CONTENT_BIT
52 | NRRD_BASIC_INFO_COMMENTS_BIT
53 | NRRD_BASIC_INFO_KEYVALUEPAIRS_BIT);
54 return 0;
55}
56*/
57
58/* ---- BEGIN non-NrrdIO */
59const int
60nrrdPresent = 42;
61
62/* ------------------------------------------------------------ */
63
64NrrdBoundarySpec *
65nrrdBoundarySpecNew(void) {
66 NrrdBoundarySpec *ret;
67
68 ret = AIR_CALLOC(1, NrrdBoundarySpec)(NrrdBoundarySpec*)(calloc((1), sizeof(NrrdBoundarySpec)));
69 if (ret) {
70 ret->boundary = nrrdBoundaryUnknown;
71 ret->padValue = AIR_NAN(airFloatQNaN.f);
72 }
73 return ret;
74}
75
76NrrdBoundarySpec *
77nrrdBoundarySpecNix(NrrdBoundarySpec *bspec) {
78
79 return airFree(bspec);
80}
81
82/* NOTE: this doesn't do a validity check! */
83NrrdBoundarySpec *
84nrrdBoundarySpecCopy(const NrrdBoundarySpec *bspec) {
85 NrrdBoundarySpec *ret;
86
87 if (bspec) {
88 ret = nrrdBoundarySpecNew();
89 ret->boundary = bspec->boundary;
90 ret->padValue = bspec->padValue;
91 } else {
92 ret = NULL((void*)0);
93 }
94 return ret;
95}
96
97int
98nrrdBoundarySpecCheck(const NrrdBoundarySpec *bspec) {
99 static const char me[]="nrrdBoundarySpecCheck";
100
101 if (!bspec) {
102 biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer", me);
103 return 1;
104 }
105 if (airEnumValCheck(nrrdBoundary, bspec->boundary)) {
106 biffAddf(NRRDnrrdBiffKey, "%s: %d is not a valid %s value", me,
107 bspec->boundary, nrrdBoundary->name);
108 return 1;
109 }
110 if (nrrdBoundaryPad == bspec->boundary) {
111 if (!AIR_EXISTS(bspec->padValue)(((int)(!((bspec->padValue) - (bspec->padValue)))))) {
112 biffAddf(NRRDnrrdBiffKey, "%s: need existing pad value (not %g) with %s %s",
113 me, bspec->padValue, nrrdBoundary->name,
114 airEnumStr(nrrdBoundary, nrrdBoundaryPad));
115 return 1;
116 }
117 }
118 return 0;
119}
120
121int
122nrrdBoundarySpecParse(NrrdBoundarySpec *bspec, const char *_str) {
123 static const char me[]="nrrdBoundarySpecParse";
124 char *str, *parm;
125 airArray *mop;
126
127 if (!(bspec && _str)) {
128 biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer", me);
129 return 1;
130 }
131 str = airStrdup(_str);
132 if (!str) {
133 biffAddf(NRRDnrrdBiffKey, "%s: couldn't copy string", me);
134 return 1;
135 }
136 mop = airMopNew();
137 airMopAdd(mop, str, airFree, airMopAlways);
138 parm = strchr(str, ':');
139 if (parm) {
140 *parm = '\0';
141 parm++;
142 }
143 bspec->boundary = airEnumVal(nrrdBoundary, str);
144 if (nrrdBoundaryUnknown == bspec->boundary) {
145 biffAddf(NRRDnrrdBiffKey, "%s: couldn't parse %s as a %s", me,
146 str, nrrdBoundary->name);
147 airMopError(mop); return 1;
148 }
149 if (parm) {
150 if (nrrdBoundaryPad != bspec->boundary) {
151 biffAddf(NRRDnrrdBiffKey, "%s: can only have parms for %s (not %s)", me,
152 airEnumStr(nrrdBoundary, nrrdBoundaryPad),
153 airEnumStr(nrrdBoundary, bspec->boundary));
154 airMopError(mop); return 1;
155 }
156 if (1 != sscanf(parm, "%lg", &(bspec->padValue))) {
157 biffAddf(NRRDnrrdBiffKey, "%s: couldn't parse \"%s\" as double", me, parm);
158 airMopError(mop); return 1;
159 }
160 if (!AIR_EXISTS(bspec->padValue)(((int)(!((bspec->padValue) - (bspec->padValue)))))) {
161 biffAddf(NRRDnrrdBiffKey, "%s: need existant pad value (not %g)", me,
162 bspec->padValue);
163 airMopError(mop); return 1;
164 }
165 } else {
166 if (nrrdBoundaryPad == bspec->boundary) {
167 biffAddf(NRRDnrrdBiffKey, "%s: need padValue parm for %s", me,
168 airEnumStr(nrrdBoundary, nrrdBoundaryPad));
169 airMopError(mop); return 1;
170 }
171 bspec->padValue = AIR_NAN(airFloatQNaN.f);
172 }
173 airMopOkay(mop);
174 return 0;
175}
176
177int
178nrrdBoundarySpecSprint(char str[AIR_STRLEN_LARGE(512+1)],
179 const NrrdBoundarySpec *bspec) {
180 static const char me[]="nrrdBoundarySpecSprint";
181 char *out;
182
183 if (!( str && bspec )) {
184 biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer", me);
185 return 1;
186 }
187 if (nrrdBoundarySpecCheck(bspec)) {
188 biffAddf(NRRDnrrdBiffKey, "%s: problem", me);
189 return 1;
190 }
191 out = str;
192 sprintf(out, "%s", airEnumStr(nrrdBoundary, bspec->boundary))__builtin___sprintf_chk (out, 0, __builtin_object_size (out, 2
> 1 ? 1 : 0), "%s", airEnumStr(nrrdBoundary, bspec->boundary
))
;
193 out += strlen(out);
194 if (nrrdBoundaryPad == bspec->boundary) {
195 sprintf(out, ":%.17g", bspec->padValue)__builtin___sprintf_chk (out, 0, __builtin_object_size (out, 2
> 1 ? 1 : 0), ":%.17g", bspec->padValue)
;
196 }
197 return 0;
198}
199
200int
201nrrdBoundarySpecCompare(const NrrdBoundarySpec *aa,
202 const NrrdBoundarySpec *bb,
203 int *differ, char explain[AIR_STRLEN_LARGE(512+1)]) {
204 static const char me[]="nrrdBoundarySpecEqual";
205
206 if (!differ) {
207 biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer", me);
208 return 1;
209 }
210 if (!!aa != !!bb) {
211 if (explain) {
212 sprintf(explain, "NULL-ities differ: %s != %s",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "NULL-ities differ: %s != %s", aa ? "non-NULL"
: "NULL", bb ? "non-NULL" : "NULL")
213 aa ? "non-NULL" : "NULL",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "NULL-ities differ: %s != %s", aa ? "non-NULL"
: "NULL", bb ? "non-NULL" : "NULL")
214 bb ? "non-NULL" : "NULL")__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "NULL-ities differ: %s != %s", aa ? "non-NULL"
: "NULL", bb ? "non-NULL" : "NULL")
;
215 }
216 *differ = 1; return 0;
217 }
218 if (!aa) {
219 /* got two NULL boundary specs ==> equal */
220 *differ = 0; return 0;
221 }
222 if (aa->boundary != bb->boundary) {
223 if (explain) {
224 sprintf(explain, "boundaries differ: %s != %s",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "boundaries differ: %s != %s", airEnumStr
(nrrdBoundary, aa->boundary), airEnumStr(nrrdBoundary, bb->
boundary))
225 airEnumStr(nrrdBoundary, aa->boundary),__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "boundaries differ: %s != %s", airEnumStr
(nrrdBoundary, aa->boundary), airEnumStr(nrrdBoundary, bb->
boundary))
226 airEnumStr(nrrdBoundary, bb->boundary))__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "boundaries differ: %s != %s", airEnumStr
(nrrdBoundary, aa->boundary), airEnumStr(nrrdBoundary, bb->
boundary))
;
227 }
228 *differ = 1; return 0;
229 }
230 if (nrrdBoundaryPad == aa->boundary) {
231 if (aa->padValue != bb->padValue) {
232 if (explain) {
233 sprintf(explain, "padValue differ: %.17g != %.17g",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "padValue differ: %.17g != %.17g", aa->
padValue, bb->padValue)
234 aa->padValue, bb->padValue)__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "padValue differ: %.17g != %.17g", aa->
padValue, bb->padValue)
;
235 }
236 *differ = 1; return 0;
237 }
238 }
239 *differ = 0;
240 return 0;
241}
242
243/* ---- END non-NrrdIO */
244/* ------------------------------------------------------------ */
245
246void
247nrrdIoStateInit(NrrdIoState *nio) {
248
249 if (nio) {
250 nio->path = (char *)airFree(nio->path);
251 nio->base = (char *)airFree(nio->base);
252 nio->line = (char *)airFree(nio->line);
253 nio->dataFNFormat = (char *)airFree(nio->dataFNFormat);
254 /* the way IO to/from strings works, I don't think this should be freed */
255 nio->headerStringRead = NULL((void*)0);
256 nio->headerStringWrite = NULL((void*)0);
257 airArrayLenSet(nio->dataFNArr, 0);
258 airArrayLenSet(nio->dataFSkipArr, 0);
259 /* closing this is always someone else's responsibility */
260 nio->headerFile = NULL((void*)0);
261 nio->dataFile = NULL((void*)0);
262 nio->dataFileDim = 0;
263 nio->dataFNMin = 0;
264 nio->dataFNMax = 0;
265 nio->dataFNStep = 0;
266 nio->dataFNIndex = 0;
267 nio->lineLen = 0;
268 nio->pos = 0;
269 nio->endian = airEndianUnknown;
270 nio->lineSkip = 0;
271 nio->headerStrlen = 0;
272 nio->headerStrpos = 0;
273 nio->byteSkip = 0;
274 memset(nio->seen, 0, (NRRD_FIELD_MAX+1)*sizeof(int))__builtin___memset_chk (nio->seen, 0, (32 +1)*sizeof(int),
__builtin_object_size (nio->seen, 0))
;
275 nio->detachedHeader = AIR_FALSE0;
276 nio->bareText = nrrdDefaultWriteBareText;
277 nio->charsPerLine = nrrdDefaultWriteCharsPerLine;
278 nio->valsPerLine = nrrdDefaultWriteValsPerLine;
279 nio->skipData = AIR_FALSE0;
280 nio->skipFormatURL = AIR_FALSE0;
281 nio->keepNrrdDataFileOpen = AIR_FALSE0;
282 nio->zlibLevel = -1;
283 nio->zlibStrategy = nrrdZlibStrategyDefault;
284 nio->bzip2BlockSize = -1;
285 nio->learningHeaderStrlen = AIR_FALSE0;
286 nio->oldData = NULL((void*)0);
287 nio->oldDataSize = 0;
288 nio->format = nrrdFormatUnknown;
289 nio->encoding = nrrdEncodingUnknown;
290 }
291 return;
292}
293
294NrrdIoState *
295nrrdIoStateNew(void) {
296 NrrdIoState *nio;
297
298 nio = (NrrdIoState *)calloc(1, sizeof(NrrdIoState));
299 if (nio) {
300 airPtrPtrUnion appu;
301
302 nio->path = NULL((void*)0);
303 nio->base = NULL((void*)0);
304 nio->line = NULL((void*)0);
305 nio->dataFNFormat = NULL((void*)0);
306 nio->dataFN = NULL((void*)0);
307 nio->headerStringRead = NULL((void*)0);
308 nio->headerStringWrite = NULL((void*)0);
309 appu.cp = &(nio->dataFN);
310 nio->dataFNArr = airArrayNew(appu.v, NULL((void*)0),
311 sizeof(char *), NRRD_FILENAME_INCR32);
312 airArrayPointerCB(nio->dataFNArr, airNull, airFree);
313 nio->dataFSkip = NULL((void*)0);
314 appu.li = &(nio->dataFSkip);
315 nio->dataFSkipArr = airArrayNew(appu.v, NULL((void*)0),
316 sizeof(long int), NRRD_FILENAME_INCR32);
317 nio->format = nrrdFormatUnknown;
318 nio->encoding = nrrdEncodingUnknown;
319 nrrdIoStateInit(nio);
320 }
321 return nio;
322}
323
324NrrdIoState *
325nrrdIoStateNix(NrrdIoState *nio) {
326
327 nio->path = (char *)airFree(nio->path);
328 nio->base = (char *)airFree(nio->base);
329 nio->line = (char *)airFree(nio->line);
330 nio->dataFNFormat = (char *)airFree(nio->dataFNFormat);
331 nio->dataFNArr = airArrayNuke(nio->dataFNArr);
332 nio->dataFSkipArr = airArrayNuke(nio->dataFSkipArr);
333 /* the NrrdIoState never owned nio->oldData; we don't free it */
334 airFree(nio); /* no NULL assignment, else compile warnings */
335 return NULL((void*)0);
336}
337
338/* ---- BEGIN non-NrrdIO */
339
340/* ------------------------------------------------------------ */
341
342void
343_nrrdResampleInfoInit(NrrdResampleInfo *info) {
344 int i, d;
345
346 for (d=0; d<NRRD_DIM_MAX16; d++) {
347 info->kernel[d] = NULL((void*)0);
348 info->samples[d] = 0;
349 info->parm[d][0] = nrrdDefaultKernelParm0;
350 for (i=1; i<NRRD_KERNEL_PARMS_NUM8; i++)
351 info->parm[d][i] = AIR_NAN(airFloatQNaN.f);
352 info->min[d] = info->max[d] = AIR_NAN(airFloatQNaN.f);
353 }
354 info->boundary = nrrdDefaultResampleBoundary;
355 info->type = nrrdDefaultResampleType;
356 info->renormalize = nrrdDefaultResampleRenormalize;
357 info->round = nrrdDefaultResampleRound;
358 info->clamp = nrrdDefaultResampleClamp;
359 info->cheap = nrrdDefaultResampleCheap;
360 info->padValue = nrrdDefaultResamplePadValue;
361}
362
363NrrdResampleInfo *
364nrrdResampleInfoNew(void) {
365 NrrdResampleInfo *info;
366
367 info = (NrrdResampleInfo*)(calloc(1, sizeof(NrrdResampleInfo)));
368 if (info) {
369 /* explicitly sets pointers to NULL */
370 _nrrdResampleInfoInit(info);
371 }
372 return info;
373}
374
375NrrdResampleInfo *
376nrrdResampleInfoNix(NrrdResampleInfo *info) {
377
378 info = (NrrdResampleInfo *)airFree(info);
379 return NULL((void*)0);
380}
381
382/* ------------------------------------------------------------ */
383
384NrrdKernelSpec *
385nrrdKernelSpecNew(void) {
386 NrrdKernelSpec *ksp;
387 int i;
388
389 ksp = (NrrdKernelSpec *)calloc(1, sizeof(NrrdKernelSpec));
390 if (ksp) {
391 ksp->kernel = NULL((void*)0);
392 for (i=0; i<NRRD_KERNEL_PARMS_NUM8; i++) {
393 ksp->parm[i] = airNaN(); /* valgrind complained about AIR_NAN at -O2 */
394 }
395 }
396 return ksp;
397}
398
399NrrdKernelSpec *
400nrrdKernelSpecCopy(const NrrdKernelSpec *oldKsp) {
401 NrrdKernelSpec *ksp=NULL((void*)0);
402
403 if (oldKsp) {
404 ksp = (NrrdKernelSpec *)calloc(1, sizeof(NrrdKernelSpec));
405 if (ksp) {
406 memcpy(ksp, oldKsp, sizeof(NrrdKernelSpec))__builtin___memcpy_chk (ksp, oldKsp, sizeof(NrrdKernelSpec), __builtin_object_size
(ksp, 0))
;
407 }
408 }
409 return ksp;
410}
411
412NrrdKernelSpec *
413nrrdKernelSpecNix(NrrdKernelSpec *ksp) {
414
415 ksp = (NrrdKernelSpec *)airFree(ksp);
Value stored to 'ksp' is never read
416 return NULL((void*)0);
417}
418
419void
420nrrdKernelSpecSet(NrrdKernelSpec *ksp, const NrrdKernel *k,
421 const double kparm[NRRD_KERNEL_PARMS_NUM8]) {
422 unsigned int p;
423
424 if (ksp && k && kparm) {
425 ksp->kernel = k;
426 for (p=0; p<(k->numParm); p++) {
427 ksp->parm[p] = kparm[p];
428 }
429 }
430}
431
432void
433nrrdKernelParmSet(const NrrdKernel **kP, double kparm[NRRD_KERNEL_PARMS_NUM8],
434 NrrdKernelSpec *ksp) {
435 int p;
436
437 if (kP && kparm && ksp) {
438 *kP = ksp->kernel;
439 for (p=0; p<NRRD_KERNEL_PARMS_NUM8; p++) {
440 kparm[p] = ksp->parm[p];
441 }
442 }
443}
444
445/* ---- END non-NrrdIO */
446
447/* ------------------------------------------------------------ */
448
449/* see axis.c for axis-specific "methods" */
450
451/* ------------------------------------------------------------ */
452
453/*
454******** nrrdBasicInfoInit
455**
456** resets "basic" (per-array) information
457** formerly nrrdPeripheralInit
458**
459** the bitflag communicates which fields should *not* be initialized
460*/
461void
462nrrdBasicInfoInit(Nrrd *nrrd, int bitflag) {
463 int dd, ee;
464
465 if (!nrrd) {
466 return;
467 }
468
469 if (!(NRRD_BASIC_INFO_DATA_BIT(1<< 1) & bitflag)) {
470 nrrd->data = airFree(nrrd->data);
471 }
472 if (!(NRRD_BASIC_INFO_TYPE_BIT(1<< 2) & bitflag)) {
473 nrrd->type = nrrdTypeUnknown;
474 }
475 if (!(NRRD_BASIC_INFO_BLOCKSIZE_BIT(1<< 3) & bitflag)) {
476 nrrd->blockSize = 0;
477 }
478 if (!(NRRD_BASIC_INFO_DIMENSION_BIT(1<< 4) & bitflag)) {
479 nrrd->dim = 0;
480 }
481 if (!(NRRD_BASIC_INFO_CONTENT_BIT(1<< 5) & bitflag)) {
482 nrrd->content = (char *)airFree(nrrd->content);
483 }
484 if (!(NRRD_BASIC_INFO_SAMPLEUNITS_BIT(1<< 6) & bitflag)) {
485 nrrd->sampleUnits = (char *)airFree(nrrd->sampleUnits);
486 }
487 if (!(NRRD_BASIC_INFO_SPACE_BIT(1<< 7) & bitflag)) {
488 nrrd->space = nrrdSpaceUnknown;
489 nrrd->spaceDim = 0;
490 }
491 if (!(NRRD_BASIC_INFO_SPACEDIMENSION_BIT(1<< 8) & bitflag)) {
492 nrrd->space = nrrdSpaceUnknown;
493 nrrd->spaceDim = 0;
494 }
495 if (!(NRRD_BASIC_INFO_SPACEUNITS_BIT(1<< 9) & bitflag)) {
496 for (dd=0; dd<NRRD_SPACE_DIM_MAX8; dd++) {
497 nrrd->spaceUnits[dd] = (char *)airFree(nrrd->spaceUnits[dd]);
498 }
499 }
500 if (!(NRRD_BASIC_INFO_SPACEORIGIN_BIT(1<<10) & bitflag)) {
501 for (dd=0; dd<NRRD_SPACE_DIM_MAX8; dd++) {
502 nrrd->spaceOrigin[dd] = AIR_NAN(airFloatQNaN.f);
503 }
504 }
505 if (!(NRRD_BASIC_INFO_MEASUREMENTFRAME_BIT(1<<11) & bitflag)) {
506 for (dd=0; dd<NRRD_SPACE_DIM_MAX8; dd++) {
507 for (ee=0; ee<NRRD_SPACE_DIM_MAX8; ee++) {
508 nrrd->measurementFrame[dd][ee] = AIR_NAN(airFloatQNaN.f);
509 }
510 }
511 }
512 if (!(NRRD_BASIC_INFO_OLDMIN_BIT(1<<12) & bitflag)) {
513 nrrd->oldMin = AIR_NAN(airFloatQNaN.f);
514 }
515 if (!(NRRD_BASIC_INFO_OLDMAX_BIT(1<<13) & bitflag)) {
516 nrrd->oldMax = AIR_NAN(airFloatQNaN.f);
517 }
518 if (!(NRRD_BASIC_INFO_COMMENTS_BIT(1<<14) & bitflag)) {
519 nrrdCommentClear(nrrd);
520 }
521 if (!(NRRD_BASIC_INFO_KEYVALUEPAIRS_BIT(1<<15) & bitflag)) {
522 nrrdKeyValueClear(nrrd);
523 }
524 return;
525}
526
527/*
528******** nrrdBasicInfoCopy
529**
530** copies "basic" (per-array) information
531** formerly known as nrrdPeripheralCopy, which was not used consistently
532**
533** the bitflag communicates which fields should *not* be copied
534*/
535int
536nrrdBasicInfoCopy(Nrrd *dest, const Nrrd *src, int bitflag) {
537 static const char me[]="nrrdBasicInfoCopy";
538 unsigned int dd, ee;
539
540 if (!( dest && src ))
541 return 0;
542 if (dest == src) {
543 /* nothing to do */
544 return 0;
545 }
546
547 if (!(NRRD_BASIC_INFO_DATA_BIT(1<< 1) & bitflag)) {
548 dest->data = src->data;
549 }
550 if (!(NRRD_BASIC_INFO_TYPE_BIT(1<< 2) & bitflag)) {
551 dest->type = src->type;
552 }
553 if (!(NRRD_BASIC_INFO_BLOCKSIZE_BIT(1<< 3) & bitflag)) {
554 dest->blockSize = src->blockSize;
555 }
556 if (!(NRRD_BASIC_INFO_DIMENSION_BIT(1<< 4) & bitflag)) {
557 dest->dim = src->dim;
558 }
559 if (!(NRRD_BASIC_INFO_CONTENT_BIT(1<< 5) & bitflag)) {
560 dest->content = (char *)airFree(dest->content);
561 dest->content = airStrdup(src->content);
562 if (src->content && !dest->content) {
563 biffAddf(NRRDnrrdBiffKey, "%s: couldn't copy content", me);
564 return 1;
565 }
566 }
567 if (!(NRRD_BASIC_INFO_SAMPLEUNITS_BIT(1<< 6) & bitflag)) {
568 dest->sampleUnits = (char *)airFree(dest->sampleUnits);
569 dest->sampleUnits = airStrdup(src->sampleUnits);
570 if (src->sampleUnits && !dest->sampleUnits) {
571 biffAddf(NRRDnrrdBiffKey, "%s: couldn't copy sampleUnits", me);
572 return 1;
573 }
574 }
575 if (!(NRRD_BASIC_INFO_SPACE_BIT(1<< 7) & bitflag)) {
576 dest->space = src->space;
577 }
578 if (!(NRRD_BASIC_INFO_SPACEDIMENSION_BIT(1<< 8) & bitflag)) {
579 dest->spaceDim = src->spaceDim;
580 }
581 if (!(NRRD_BASIC_INFO_SPACEUNITS_BIT(1<< 9) & bitflag)) {
582 for (dd=0; dd<src->spaceDim; dd++) {
583 dest->spaceUnits[dd] = (char *)airFree(dest->spaceUnits[dd]);
584 dest->spaceUnits[dd] = airStrdup(src->spaceUnits[dd]);
585 if (src->spaceUnits[dd] && !dest->spaceUnits[dd]) {
586 biffAddf(NRRDnrrdBiffKey, "%s: couldn't copy spaceUnits[%d]", me, dd);
587 return 1;
588 }
589 }
590 for (dd=src->spaceDim; dd<NRRD_SPACE_DIM_MAX8; dd++) {
591 dest->spaceUnits[dd] = (char *)airFree(dest->spaceUnits[dd]);
592 }
593 }
594 if (!(NRRD_BASIC_INFO_SPACEORIGIN_BIT(1<<10) & bitflag)) {
595 for (dd=0; dd<NRRD_SPACE_DIM_MAX8; dd++) {
596 if (dd <= src->spaceDim-1) {
597 dest->spaceOrigin[dd] = src->spaceOrigin[dd];
598 } else {
599 dest->spaceOrigin[dd] = AIR_NAN(airFloatQNaN.f);
600 }
601 }
602 }
603 if (!(NRRD_BASIC_INFO_MEASUREMENTFRAME_BIT(1<<11) & bitflag)) {
604 for (dd=0; dd<NRRD_SPACE_DIM_MAX8; dd++) {
605 for (ee=0; ee<NRRD_SPACE_DIM_MAX8; ee++) {
606 if (dd <= src->spaceDim-1 && ee <= src->spaceDim-1) {
607 dest->measurementFrame[dd][ee] = src->measurementFrame[dd][ee];
608 } else {
609 dest->measurementFrame[dd][ee] = AIR_NAN(airFloatQNaN.f);
610 }
611 }
612 }
613 for (dd=src->spaceDim; dd<NRRD_SPACE_DIM_MAX8; dd++) {
614 dest->spaceOrigin[dd] = AIR_NAN(airFloatQNaN.f);
615 }
616 }
617 if (!(NRRD_BASIC_INFO_OLDMIN_BIT(1<<12) & bitflag)) {
618 dest->oldMin = src->oldMin;
619 }
620 if (!(NRRD_BASIC_INFO_OLDMAX_BIT(1<<13) & bitflag)) {
621 dest->oldMax = src->oldMax;
622 }
623 if (!(NRRD_BASIC_INFO_COMMENTS_BIT(1<<14) & bitflag)) {
624 if (nrrdCommentCopy(dest, src)) {
625 biffAddf(NRRDnrrdBiffKey, "%s: trouble copying comments", me);
626 return 1;
627 }
628 }
629 if (!(NRRD_BASIC_INFO_KEYVALUEPAIRS_BIT(1<<15) & bitflag)) {
630 if (nrrdKeyValueCopy(dest, src)) {
631 biffAddf(NRRDnrrdBiffKey, "%s: trouble copying key/value pairs", me);
632 return 1;
633 }
634 }
635 return 0;
636}
637
638/*
639******* nrrdInit
640**
641** initializes a nrrd to default state. All nrrd functions in the
642** business of initializing a nrrd struct use this function. Mostly
643** just sets values to 0, NaN, "", NULL, or Unknown
644*/
645void
646nrrdInit(Nrrd *nrrd) {
647 int ii;
648
649 if (nrrd) {
650 nrrdBasicInfoInit(nrrd, NRRD_BASIC_INFO_NONE0);
651 for (ii=0; ii<NRRD_DIM_MAX16; ii++) {
652 _nrrdAxisInfoInit(nrrd->axis + ii);
653 }
654 }
655 return;
656}
657
658/*
659******** nrrdNew()
660**
661** creates and initializes a Nrrd
662**
663** this does NOT use biff
664*/
665Nrrd *
666nrrdNew(void) {
667 int ii;
668 Nrrd *nrrd;
669 airPtrPtrUnion appu;
670
671 nrrd = (Nrrd*)(calloc(1, sizeof(Nrrd)));
672 if (!nrrd) {
673 return NULL((void*)0);
674 }
675
676 /* explicitly set pointers to NULL, since calloc isn't officially
677 guaranteed to do that. */
678 nrrd->data = NULL((void*)0);
679 for (ii=0; ii<NRRD_DIM_MAX16; ii++) {
680 _nrrdAxisInfoNewInit(nrrd->axis + ii);
681 }
682 for (ii=0; ii<NRRD_SPACE_DIM_MAX8; ii++) {
683 nrrd->spaceUnits[ii] = NULL((void*)0);
684 }
685 nrrd->content = NULL((void*)0);
686 nrrd->sampleUnits = NULL((void*)0);
687
688 /* create comment airArray (even though it starts empty) */
689 nrrd->cmt = NULL((void*)0);
690 appu.cp = &(nrrd->cmt);
691 nrrd->cmtArr = airArrayNew(appu.v, NULL((void*)0), sizeof(char *), NRRD_COMMENT_INCR16);
692 if (!nrrd->cmtArr) {
693 return NULL((void*)0);
694 }
695 airArrayPointerCB(nrrd->cmtArr, airNull, airFree);
696
697 /* create key/value airArray (even thought it starts empty) */
698 nrrd->kvp = NULL((void*)0);
699 appu.cp = &(nrrd->kvp);
700 nrrd->kvpArr = airArrayNew(appu.v, NULL((void*)0),
701 2*sizeof(char *), NRRD_KEYVALUE_INCR32);
702 if (!nrrd->kvpArr) {
703 return NULL((void*)0);
704 }
705 /* key/value airArray uses no callbacks for now */
706
707 /* finish initializations */
708 nrrdInit(nrrd);
709
710 return nrrd;
711}
712
713/*
714******** nrrdNix()
715**
716** does nothing with the array data inside, just does whatever is needed
717** to free the nrrd itself
718**
719** returns NULL
720**
721** this does NOT use biff
722*/
723Nrrd *
724nrrdNix(Nrrd *nrrd) {
725 int ii;
726
727 if (nrrd) {
728 for (ii=0; ii<NRRD_DIM_MAX16; ii++) {
729 _nrrdAxisInfoInit(&(nrrd->axis[ii]));
730 }
731 for (ii=0; ii<NRRD_SPACE_DIM_MAX8; ii++) {
732 nrrd->spaceUnits[ii] = (char *)airFree(nrrd->spaceUnits[ii]);
733 }
734 nrrd->content = (char *)airFree(nrrd->content);
735 nrrd->sampleUnits = (char *)airFree(nrrd->sampleUnits);
736 nrrdCommentClear(nrrd);
737 nrrd->cmtArr = airArrayNix(nrrd->cmtArr);
738 nrrdKeyValueClear(nrrd);
739 nrrd->kvpArr = airArrayNix(nrrd->kvpArr);
740 airFree(nrrd);
741 }
742 return NULL((void*)0);
743}
744
745/*
746******** nrrdEmpty()
747**
748** frees data inside nrrd AND resets all its state, so its the
749** same as what comes from nrrdNew(). This includes free()ing
750** any comments.
751*/
752Nrrd *
753nrrdEmpty(Nrrd *nrrd) {
754
755 if (nrrd) {
756 nrrd->data = airFree(nrrd->data);
757 nrrdInit(nrrd);
758 }
759 return nrrd;
760}
761
762/*
763******** nrrdNuke()
764**
765** blows away the nrrd and everything inside
766**
767** always returns NULL
768*/
769Nrrd *
770nrrdNuke(Nrrd *nrrd) {
771
772 if (nrrd) {
773 nrrdEmpty(nrrd);
774 nrrdNix(nrrd);
775 }
776 return NULL((void*)0);
777}
778
779/* ------------------------------------------------------------ */
780
781int
782_nrrdSizeCheck(const size_t *size, unsigned int dim, int useBiff) {
783 static const char me[]="_nrrdSizeCheck";
784 size_t num, pre;
785 unsigned int ai;
786
787 pre = num = 1;
788 for (ai=0; ai<dim; ai++) {
789 if (!size[ai]) {
790 biffMaybeAddf(useBiff, NRRDnrrdBiffKey, "%s: axis %u size is zero!", me, ai);
791 return 1;
792 }
793 num *= size[ai];
794 if (num/size[ai] != pre) {
795 biffMaybeAddf(useBiff, NRRDnrrdBiffKey,
796 "%s: total # of elements too large to be represented in "
797 "type size_t, so too large for current architecture", me);
798 return 1;
799 }
800 pre *= size[ai];
801 }
802 return 0;
803}
804
805/*
806******** nrrdWrap_nva()
807**
808** wraps a given Nrrd around a given array
809**
810** we don't touch any of the peripheral information (content, comments,
811** blocksize, min/max) because it is entirely reasonable to be setting
812** this before or after this call. "type" could be passed as
813** nrrdTypeBlock, in which case it is the user's responsibility to
814** set nrrd->blockSize at some other time.
815*/
816int
817nrrdWrap_nva(Nrrd *nrrd, void *data, int type,
818 unsigned int dim, const size_t *size) {
819 static const char me[]="nrrdWrap_nva";
820
821 if (!(nrrd && size)) {
822 biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer", me);
823 return 1;
824 }
825 nrrd->data = data;
826 nrrd->type = type;
827 nrrd->dim = dim;
828 if (_nrrdSizeCheck(size, dim, AIR_TRUE1)) {
829 biffAddf(NRRDnrrdBiffKey, "%s:", me);
830 return 1;
831 }
832 nrrdAxisInfoSet_nva(nrrd, nrrdAxisInfoSize, size);
833 return 0;
834}
835
836/*
837******** nrrdWrap_va()
838**
839** Minimal var args wrapper around nrrdWrap_nva, with the advantage of
840** taking all the axes sizes as the var args.
841**
842** This is THE BEST WAY to wrap a nrrd around existing raster data,
843** assuming that the dimension is known at compile time.
844**
845** If successful, returns 0, otherwise, 1.
846** This does use biff.
847*/
848int
849nrrdWrap_va(Nrrd *nrrd, void *data, int type, unsigned int dim, ...) {
850 static const char me[]="nrrdWrap_va";
851 va_list ap;
852 size_t size[NRRD_DIM_MAX16];
853 unsigned int ai;
854
855 if (!(nrrd && data)) {
856 biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer", me);
857 return 1;
858 }
859 va_start(ap, dim)__builtin_va_start(ap, dim);
860 for (ai=0; ai<dim; ai++) {
861 size[ai] = va_arg(ap, size_t)__builtin_va_arg(ap, size_t);
862 }
863 va_end(ap)__builtin_va_end(ap);
864
865 return nrrdWrap_nva(nrrd, data, type, dim, size);
866}
867
868/*
869void
870_nrrdTraverse(Nrrd *nrrd) {
871 char *test, tval;
872 size_t I, N;
873 int S;
874
875 N = nrrdElementNumber(nrrd);
876 S = nrrdElementSize(nrrd);
877 tval = 0;
878 test = nrrd->data;
879 for (I=0; I<N*S; I++) {
880 tval += test[I];
881 }
882}
883*/
884
885int
886_nrrdCopy(Nrrd *nout, const Nrrd *nin, int bitflag) {
887 static const char me[]="_nrrdCopy";
888 size_t size[NRRD_DIM_MAX16];
889
890 if (!(nin && nout)) {
891 biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer", me);
892 return 1;
893 }
894 if (nout == nin) {
895 /* its not the case that we have nothing to do- the semantics of
896 copying cannot be achieved if the input and output nrrd are
897 the same; this is an error */
898 biffAddf(NRRDnrrdBiffKey, "%s: nout==nin disallowed", me);
899 return 1;
900 }
901 if (!nrrdElementSize(nin)) {
902 biffAddf(NRRDnrrdBiffKey, "%s: input nrrd reports zero element size!", me);
903 return 1;
904 }
905 nrrdAxisInfoGet_nva(nin, nrrdAxisInfoSize, size);
906 if (nin->data) {
907 if (nrrdMaybeAlloc_nva(nout, nin->type, nin->dim, size)) {
908 biffAddf(NRRDnrrdBiffKey, "%s: couldn't allocate data", me);
909 return 1;
910 }
911 memcpy(nout->data, nin->data,__builtin___memcpy_chk (nout->data, nin->data, nrrdElementNumber
(nin)*nrrdElementSize(nin), __builtin_object_size (nout->data
, 0))
912 nrrdElementNumber(nin)*nrrdElementSize(nin))__builtin___memcpy_chk (nout->data, nin->data, nrrdElementNumber
(nin)*nrrdElementSize(nin), __builtin_object_size (nout->data
, 0))
;
913 } else {
914 /* someone is trying to copy structs without data, fine fine fine */
915 if (nrrdWrap_nva(nout, NULL((void*)0), nin->type, nin->dim, size)) {
916 biffAddf(NRRDnrrdBiffKey, "%s: couldn't wrap NULL data", me);
917 return 1;
918 }
919 }
920 nrrdAxisInfoCopy(nout, nin, NULL((void*)0), NRRD_AXIS_INFO_SIZE_BIT(1<< 1));
921 /* if nin->data non-NULL (second branch above), this will
922 harmlessly unset and set type and dim */
923 nrrdBasicInfoInit(nout, NRRD_BASIC_INFO_DATA_BIT(1<< 1) | bitflag);
924 if (nrrdBasicInfoCopy(nout, nin, NRRD_BASIC_INFO_DATA_BIT(1<< 1) | bitflag)) {
925 biffAddf(NRRDnrrdBiffKey, "%s: trouble copying basic info", me);
926 return 1;
927 }
928
929 return 0;
930}
931
932/*
933******** nrrdCopy
934**
935** copy method for nrrds. nout will end up as an "exact" copy of nin.
936** New space for data is allocated here, and output nrrd points to it.
937** Comments from old are added to comments for new, so these are also
938** newly allocated. nout->ptr is not set, nin->ptr is not read.
939*/
940int
941nrrdCopy(Nrrd *nout, const Nrrd *nin) {
942 static const char me[]="nrrdCopy";
943
944 if (_nrrdCopy(nout, nin, NRRD_BASIC_INFO_NONE0)) {
945 biffAddf(NRRDnrrdBiffKey, "%s:", me);
946 return 1;
947 }
948 return 0;
949}
950
951/*
952******** nrrdAlloc_nva()
953**
954** allocates data array and sets information. If this is a block type
955** nrrd, it is necessary to set nrrd->blockSize PRIOR to calling
956** this function.
957**
958** This function will always allocate more memory (via calloc), but
959** it will free() nrrd->data if it is non-NULL when passed in.
960**
961** This function takes the same "don't mess with peripheral information"
962** attitude as nrrdWrap().
963**
964** Note to Gordon: don't get clever and change ANY axis-specific
965** information here. It may be very convenient to set that before
966** nrrdAlloc or nrrdMaybeAlloc
967**
968** Note: This function DOES use biff
969*/
970int
971nrrdAlloc_nva(Nrrd *nrrd, int type, unsigned int dim, const size_t *size) {
972 static const char me[]="nrrdAlloc_nva";
973 size_t num, esize;
974 char stmp[2][AIR_STRLEN_SMALL(128+1)];
975
976 if (!(nrrd && size)) {
977 biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer", me);
978 return 1;
979 }
980 if (airEnumValCheck(nrrdType, type)) {
981 biffAddf(NRRDnrrdBiffKey, "%s: type (%d) is invalid", me, type);
982 return 1;
983 }
984 if (nrrdTypeBlock == type) {
985 if (!(0 < nrrd->blockSize)) {
986 biffAddf(NRRDnrrdBiffKey, "%s: given nrrd->blockSize %s invalid", me,
987 airSprintSize_t(stmp[0], nrrd->blockSize));
988 return 1;
989 }
990 }
991 if (!AIR_IN_CL(1, dim, NRRD_DIM_MAX)((1) <= (dim) && (dim) <= (16))) {
992 biffAddf(NRRDnrrdBiffKey, "%s: dim (%d) not in valid range [1,%d]",
993 me, dim, NRRD_DIM_MAX16);
994 return 1;
995 }
996
997 nrrd->data = airFree(nrrd->data);
998 if (nrrdWrap_nva(nrrd, NULL((void*)0), type, dim, size)) {
999 biffAddf(NRRDnrrdBiffKey, "%s:", me);
1000 return 1 ;
1001 }
1002 num = nrrdElementNumber(nrrd);
1003 esize = nrrdElementSize(nrrd);
1004 nrrd->data = calloc(num, esize);
1005 if (!(nrrd->data)) {
1006 biffAddf(NRRDnrrdBiffKey, "%s: calloc(%s,%s) failed", me,
1007 airSprintSize_t(stmp[0], num),
1008 airSprintSize_t(stmp[1], esize));
1009 return 1 ;
1010 }
1011
1012 return 0;
1013}
1014
1015/*
1016******** nrrdAlloc_va()
1017**
1018** Handy wrapper around nrrdAlloc_nva, which takes, as its vararg list,
1019** all the axes sizes.
1020*/
1021int
1022nrrdAlloc_va(Nrrd *nrrd, int type, unsigned int dim, ...) {
1023 static const char me[]="nrrdAlloc_va";
1024 size_t size[NRRD_DIM_MAX16];
1025 unsigned int ai;
1026 va_list ap;
1027
1028 if (!nrrd) {
1029 biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer", me);
1030 return 1;
1031 }
1032 va_start(ap, dim)__builtin_va_start(ap, dim);
1033 for (ai=0; ai<dim; ai++) {
1034 size[ai] = va_arg(ap, size_t)__builtin_va_arg(ap, size_t);
1035 }
1036 va_end(ap)__builtin_va_end(ap);
1037 if (nrrdAlloc_nva(nrrd, type, dim, size)) {
1038 biffAddf(NRRDnrrdBiffKey, "%s:", me);
1039 return 1;
1040 }
1041 return 0;
1042}
1043
1044
1045/*
1046** _nrrdMaybeAllocMaybeZero_nva
1047**
1048** New implementation of nrrdMaybeAlloc_nva, but now with ability
1049** to control whether or not to zero out when re-allocation wasn't needed
1050**
1051** HEY: should consider making this a public function, but GLK couldn't
1052** think of a name that wasn't silly
1053*/
1054int
1055_nrrdMaybeAllocMaybeZero_nva(Nrrd *nrrd, int type,
1056 unsigned int dim, const size_t *size,
1057 int zeroWhenNoAlloc) {
1058 static const char me[]="nrrdMaybeAllocMaybeZero_nva";
1059 size_t sizeWant, sizeHave, numWant, elementSizeWant;
1060 int need;
1061 unsigned int ai;
1062
1063 if (!nrrd) {
1064 biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer", me);
1065 return 1;
1066 }
1067 if (airEnumValCheck(nrrdType, type)) {
1068 biffAddf(NRRDnrrdBiffKey, "%s: type (%d) is invalid", me, type);
1069 return 1;
1070 }
1071 if (nrrdTypeBlock == type) {
1072 if (nrrdTypeBlock == nrrd->type) {
1073 biffAddf(NRRDnrrdBiffKey, "%s: can't change from one block nrrd to another", me);
1074 return 1;
1075 }
1076 if (!(0 < nrrd->blockSize)) {
1077 char stmp[AIR_STRLEN_SMALL(128+1)];
1078 biffAddf(NRRDnrrdBiffKey, "%s: given nrrd->blockSize %s invalid", me,
1079 airSprintSize_t(stmp, nrrd->blockSize));
1080 return 1;
1081 }
1082 elementSizeWant = nrrd->blockSize;
1083 } else {
1084 elementSizeWant = nrrdTypeSize[type];
1085 }
1086 if (_nrrdSizeCheck(size, dim, AIR_TRUE1)) {
1087 biffAddf(NRRDnrrdBiffKey, "%s:", me);
1088 return 1;
1089 }
1090
1091 if (!(nrrd->data)) {
1092 need = 1;
1093 } else {
1094 numWant = 1;
1095 for (ai=0; ai<dim; ai++) {
1096 numWant *= size[ai];
1097 }
1098 if (!nrrdElementSize(nrrd)) {
1099 biffAddf(NRRDnrrdBiffKey, "%s: nrrd reports zero element size!", me);
1100 return 1;
1101 }
1102 sizeHave = nrrdElementNumber(nrrd) * nrrdElementSize(nrrd);
1103 /* fprintf(stderr, "##%s: sizeHave = %d * %d = %d\n", me,
1104 (int)(nrrdElementNumber(nrrd)),
1105 (int)(nrrdElementSize(nrrd)), (int)sizeHave); */
1106 sizeWant = numWant * elementSizeWant;
1107 /* fprintf(stderr, "##%s: sizeWant = %d * %d = %d\n", me,
1108 (int)(numWant),
1109 (int)(elementSizeWant), (int)sizeWant); */
1110 need = sizeHave != sizeWant;
1111 /* fprintf(stderr, "##%s: need = %d\n", me, need); */
1112 }
1113 if (need) {
1114 if (nrrdAlloc_nva(nrrd, type, dim, size)) {
1115 biffAddf(NRRDnrrdBiffKey, "%s:", me);
1116 return 1;
1117 }
1118 } else {
1119 /* size is already exactly what we want */
1120 if (nrrdWrap_nva(nrrd, nrrd->data, type, dim, size)) {
1121 biffAddf(NRRDnrrdBiffKey, "%s:", me);
1122 return 1;
1123 }
1124 /* but we may have to initialize memory */
1125 if (zeroWhenNoAlloc) {
1126 memset(nrrd->data, 0, nrrdElementNumber(nrrd)*nrrdElementSize(nrrd))__builtin___memset_chk (nrrd->data, 0, nrrdElementNumber(nrrd
)*nrrdElementSize(nrrd), __builtin_object_size (nrrd->data
, 0))
;
1127 }
1128 }
1129
1130 return 0;
1131}
1132
1133/*
1134******** nrrdMaybeAlloc_nva
1135**
1136** NOTE: this is now just a wrapper around _nrrdMaybeAllocMaybeZero_nva;
1137** below info referred to original implementation.
1138**
1139** calls nrrdAlloc_nva if the requested space is different than
1140** what is currently held
1141**
1142** also subscribes to the "don't mess with peripheral information" philosophy
1143*/
1144int
1145nrrdMaybeAlloc_nva(Nrrd *nrrd, int type,
1146 unsigned int dim, const size_t *size) {
1147 static const char me[]="nrrdMaybeAlloc_nva";
1148 int ret;
1149 ret = _nrrdMaybeAllocMaybeZero_nva(nrrd, type, dim, size,
1150 AIR_TRUE1);
1151 if (ret) {
1152 biffAddf(NRRDnrrdBiffKey, "%s: trouble", me);
1153 }
1154 return ret;
1155}
1156
1157/*
1158******** nrrdMaybeAlloc_va()
1159**
1160** Handy wrapper around nrrdAlloc, which takes, as its vararg list
1161** all the axes sizes, thereby calculating the total number.
1162*/
1163int
1164nrrdMaybeAlloc_va(Nrrd *nrrd, int type, unsigned int dim, ...) {
1165 static const char me[]="nrrdMaybeAlloc_va";
1166 size_t size[NRRD_DIM_MAX16];
1167 unsigned int ai;
1168 va_list ap;
1169
1170 if (!nrrd) {
1171 biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer", me);
1172 return 1;
1173 }
1174 va_start(ap, dim)__builtin_va_start(ap, dim);
1175 for (ai=0; ai<dim; ai++) {
1176 size[ai] = va_arg(ap, size_t)__builtin_va_arg(ap, size_t);
1177 }
1178 va_end(ap)__builtin_va_end(ap);
1179 if (nrrdMaybeAlloc_nva(nrrd, type, dim, size)) {
1180 biffAddf(NRRDnrrdBiffKey, "%s:", me);
1181 return 1;
1182 }
1183 return 0;
1184}
1185
1186/* ---- BEGIN non-NrrdIO */
1187
1188/*
1189** nrrdCompare
1190**
1191** walks through all fields of the two nrrds to see if they contain
1192** the same information. So, this doesn't compare any pointer values,
1193** only the contents of things.
1194**
1195** Unlike strcmp(), the return value from this can't be the indication
1196** of the difference, because we'd have to return a value even in the
1197** case of an error, which would be be strange. GLK briefly tried
1198** created a new #define _NRRD_ERROR_RETURN for this purpose (with
1199** leet-speak value 32202), but its just a bad idea.
1200**
1201** NOTE: the structure of this code is very similar to that of
1202** nrrdAxisInfoCompare, and any improvements here should be reflected there
1203*/
1204int
1205nrrdCompare(const Nrrd *ninA, const Nrrd *ninB,
1206 int onlyData, double epsilon,
1207 int *differ, char explain[AIR_STRLEN_LARGE(512+1)]) {
1208 static const char me[]="nrrdCompare";
1209 size_t numA, numB;
1210 unsigned int axi, saxi;
1211
1212 if (!(ninA && ninB && differ)) {
1213 biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer (%p, %p, or %p)", me,
1214 AIR_CVOIDP(ninA)((const void *)(ninA)), AIR_CVOIDP(ninB)((const void *)(ninB)), AIR_VOIDP(differ)((void *)(differ)));
1215 return 1;
1216 }
1217
1218 if (explain) {
1219 strcpy(explain, "")__builtin___strcpy_chk (explain, "", __builtin_object_size (explain
, 2 > 1 ? 1 : 0))
;
1220 }
1221 if (!onlyData) {
1222 if (ninA->dim != ninB->dim) {
1223 *differ = ninA->dim < ninB->dim ? -1 : 1;
1224 if (explain) {
1225 sprintf(explain, "nin{A,B}->dim %u %s %u",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "nin{A,B}->dim %u %s %u", ninA->dim
, *differ < 0 ? "<" : ">", ninB->dim)
1226 ninA->dim, *differ < 0 ? "<" : ">", ninB->dim)__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "nin{A,B}->dim %u %s %u", ninA->dim
, *differ < 0 ? "<" : ">", ninB->dim)
;
1227 }
1228 return 0;
1229 }
1230 }
1231 if (ninA->type != ninB->type) {
1232 *differ = ninA->type < ninB->type ? -1 : 1;
1233 if (explain) {
1234 sprintf(explain, "nin{A,B}->type %s %s %s",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "nin{A,B}->type %s %s %s", airEnumStr
(nrrdType, ninA->type), *differ < 0 ? "<" : ">", airEnumStr
(nrrdType, ninB->type))
1235 airEnumStr(nrrdType, ninA->type), *differ < 0 ? "<" : ">",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "nin{A,B}->type %s %s %s", airEnumStr
(nrrdType, ninA->type), *differ < 0 ? "<" : ">", airEnumStr
(nrrdType, ninB->type))
1236 airEnumStr(nrrdType, ninB->type))__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "nin{A,B}->type %s %s %s", airEnumStr
(nrrdType, ninA->type), *differ < 0 ? "<" : ">", airEnumStr
(nrrdType, ninB->type))
;
1237 }
1238 return 0;
1239 }
1240 numA = nrrdElementNumber(ninA);
1241 numB = nrrdElementNumber(ninB);
1242 if (numA != numB) {
1243 char stmp1[AIR_STRLEN_SMALL(128+1)], stmp2[AIR_STRLEN_SMALL(128+1)];
1244 *differ = numA < numB ? -1 : 1;
1245 sprintf(explain, "element # {A,B} %s %s %s",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "element # {A,B} %s %s %s", airSprintSize_t
(stmp1, numA), *differ < 0 ? "<" : ">", airSprintSize_t
(stmp2, numB))
1246 airSprintSize_t(stmp1, numA), *differ < 0 ? "<" : ">",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "element # {A,B} %s %s %s", airSprintSize_t
(stmp1, numA), *differ < 0 ? "<" : ">", airSprintSize_t
(stmp2, numB))
1247 airSprintSize_t(stmp2, numB))__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "element # {A,B} %s %s %s", airSprintSize_t
(stmp1, numA), *differ < 0 ? "<" : ">", airSprintSize_t
(stmp2, numB))
;
1248 return 0;
1249 }
1250 /* this will always set *differ */
1251 if (nrrdArrayCompare(ninA->type, ninA->data, ninB->data, numA,
1252 epsilon, differ, explain)) {
1253 biffAddf(NRRDnrrdBiffKey, "%s: problem comparing values", me);
1254 return 1;
1255 }
1256 if (onlyData || *differ) {
1257 /* If caller only cared about data values,
1258 we're done whether or not they were different.
1259 else, if the data values are different, we're done.
1260 The explanation of any difference in values is
1261 already in "explain" (if non-NULL) */
1262 return 0;
1263 }
1264
1265 for (axi=0; axi<ninA->dim; axi++) {
1266 /* this always sets *differ */
1267 if (nrrdAxisInfoCompare(ninA->axis + axi, ninB->axis + axi,
1268 differ, explain)) {
1269 biffAddf(NRRDnrrdBiffKey, "%s: problem comparing axis %u", me, axi);
1270 return 1;
1271 }
1272 if (*differ) {
1273 char tmpexplain[AIR_STRLEN_LARGE(512+1)];
1274 /* the explanation, if wanted, is in "explain", but we add context */
1275 sprintf(tmpexplain, "(axis %u) %s", axi, explain)__builtin___sprintf_chk (tmpexplain, 0, __builtin_object_size
(tmpexplain, 2 > 1 ? 1 : 0), "(axis %u) %s", axi, explain
)
;
1276 airStrcpy(explain, AIR_STRLEN_LARGE(512+1), tmpexplain);
1277 return 0;
1278 }
1279 }
1280
1281#define STRING_COMPARE(VAL, STR) \
1282 *differ = airStrcmp(ninA->VAL, ninB->VAL); \
1283 if (*differ) { \
1284 if (explain) { \
1285 /* can't print whole string because of fixed-size of explain */ \
1286 sprintf(explain, "ninA->%s %s ninB->%s", \__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA->%s %s ninB->%s", STR, *differ
< 0 ? "<" : ">", STR)
1287 STR, *differ < 0 ? "<" : ">", STR)__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA->%s %s ninB->%s", STR, *differ
< 0 ? "<" : ">", STR)
; \
1288 } \
1289 return 0; \
1290 }
1291
1292 STRING_COMPARE(content, "content");
1293 STRING_COMPARE(sampleUnits, "sampleUnits");
1294 if (ninA->space != ninB->space) {
1295 *differ = ninA->space < ninB->space ? -1 : 1;
1296 if (explain) {
1297 sprintf(explain, "ninA->space %s %s ninB->space %s",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA->space %s %s ninB->space %s"
, airEnumStr(nrrdSpace, ninA->space), *differ < 0 ? "<"
: ">", airEnumStr(nrrdSpace, ninB->space))
1298 airEnumStr(nrrdSpace, ninA->space),__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA->space %s %s ninB->space %s"
, airEnumStr(nrrdSpace, ninA->space), *differ < 0 ? "<"
: ">", airEnumStr(nrrdSpace, ninB->space))
1299 *differ < 0 ? "<" : ">",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA->space %s %s ninB->space %s"
, airEnumStr(nrrdSpace, ninA->space), *differ < 0 ? "<"
: ">", airEnumStr(nrrdSpace, ninB->space))
1300 airEnumStr(nrrdSpace, ninB->space))__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA->space %s %s ninB->space %s"
, airEnumStr(nrrdSpace, ninA->space), *differ < 0 ? "<"
: ">", airEnumStr(nrrdSpace, ninB->space))
;
1301 }
1302 return 0;
1303 }
1304 if (ninA->spaceDim != ninB->spaceDim) {
1305 *differ = ninA->spaceDim < ninB->spaceDim ? -1 : 1;
1306 if (explain) {
1307 sprintf(explain, "ninA->spaceDim %u %s ninB->spaceDim %u",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA->spaceDim %u %s ninB->spaceDim %u"
, ninA->spaceDim, *differ < 0 ? "<" : ">", ninB->
spaceDim)
1308 ninA->spaceDim, *differ < 0 ? "<" : ">", ninB->spaceDim)__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA->spaceDim %u %s ninB->spaceDim %u"
, ninA->spaceDim, *differ < 0 ? "<" : ">", ninB->
spaceDim)
;
1309 }
1310 return 0;
1311 }
1312 if (ninA->blockSize != ninB->blockSize) {
1313 *differ = ninA->blockSize < ninB->blockSize ? -1 : 1;
1314 if (explain) {
1315 char stmp1[AIR_STRLEN_SMALL(128+1)], stmp2[AIR_STRLEN_SMALL(128+1)];
1316 sprintf(explain, "ninA->blockSize %s %s ninB->blockSize %s",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA->blockSize %s %s ninB->blockSize %s"
, airSprintSize_t(stmp1, ninA->blockSize), *differ < 0 ?
"<" : ">", airSprintSize_t(stmp2, ninB->blockSize))
1317 airSprintSize_t(stmp1, ninA->blockSize),__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA->blockSize %s %s ninB->blockSize %s"
, airSprintSize_t(stmp1, ninA->blockSize), *differ < 0 ?
"<" : ">", airSprintSize_t(stmp2, ninB->blockSize))
1318 *differ < 0 ? "<" : ">",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA->blockSize %s %s ninB->blockSize %s"
, airSprintSize_t(stmp1, ninA->blockSize), *differ < 0 ?
"<" : ">", airSprintSize_t(stmp2, ninB->blockSize))
1319 airSprintSize_t(stmp2, ninB->blockSize))__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA->blockSize %s %s ninB->blockSize %s"
, airSprintSize_t(stmp1, ninA->blockSize), *differ < 0 ?
"<" : ">", airSprintSize_t(stmp2, ninB->blockSize))
;
1320 }
1321 return 0;
1322 }
1323
1324#define DOUBLE_COMPARE(VAL, STR) \
1325 *differ = _nrrdDblcmp(ninA->VAL, ninB->VAL); \
1326 if (*differ) { \
1327 if (explain) { \
1328 sprintf(explain, "ninA->%s %.17g %s ninB->%s %.17g", \__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA->%s %.17g %s ninB->%s %.17g"
, STR, ninA->VAL, *differ < 0 ? "<" : ">", STR, ninB
->VAL)
1329 STR, ninA->VAL, *differ < 0 ? "<" : ">", \__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA->%s %.17g %s ninB->%s %.17g"
, STR, ninA->VAL, *differ < 0 ? "<" : ">", STR, ninB
->VAL)
1330 STR, ninB->VAL)__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA->%s %.17g %s ninB->%s %.17g"
, STR, ninA->VAL, *differ < 0 ? "<" : ">", STR, ninB
->VAL)
; \
1331 } \
1332 return 0; \
1333 }
1334
1335 for (saxi=0; saxi<NRRD_SPACE_DIM_MAX8; saxi++) {
1336 char stmp[AIR_STRLEN_SMALL(128+1)];
1337 unsigned int saxj;
1338 sprintf(stmp, "spaceOrigin[%u]", saxi)__builtin___sprintf_chk (stmp, 0, __builtin_object_size (stmp
, 2 > 1 ? 1 : 0), "spaceOrigin[%u]", saxi)
;
1339 DOUBLE_COMPARE(spaceOrigin[saxi], stmp);
1340 sprintf(stmp, "spaceUnits[%u]", saxi)__builtin___sprintf_chk (stmp, 0, __builtin_object_size (stmp
, 2 > 1 ? 1 : 0), "spaceUnits[%u]", saxi)
;
1341 STRING_COMPARE(spaceUnits[saxi], stmp);
1342 for (saxj=0; saxj<NRRD_SPACE_DIM_MAX8; saxj++) {
1343 sprintf(stmp, "measurementFrame[%u][%u]", saxi, saxj)__builtin___sprintf_chk (stmp, 0, __builtin_object_size (stmp
, 2 > 1 ? 1 : 0), "measurementFrame[%u][%u]", saxi, saxj)
;
1344 DOUBLE_COMPARE(measurementFrame[saxi][saxj], stmp);
1345 }
1346 }
1347 DOUBLE_COMPARE(oldMin, "oldMin");
1348 DOUBLE_COMPARE(oldMax, "oldMax");
1349#undef DOUBLE_COMPARE
1350
1351 if (ninA->cmtArr->len != ninB->cmtArr->len) {
1352 *differ = ninA->cmtArr->len < ninB->cmtArr->len ? -1 : 1;
1353 if (explain) {
1354 sprintf(explain, "ninA # comments %u %s ninB # comments %u",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA # comments %u %s ninB # comments %u"
, ninA->cmtArr->len, *differ < 0 ? "<" : ">", ninB
->cmtArr->len)
1355 ninA->cmtArr->len, *differ < 0 ? "<" : ">", ninB->cmtArr->len)__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA # comments %u %s ninB # comments %u"
, ninA->cmtArr->len, *differ < 0 ? "<" : ">", ninB
->cmtArr->len)
;
1356 }
1357 return 0;
1358 } else {
1359 unsigned int ii;
1360 char stmp[AIR_STRLEN_SMALL(128+1)];
1361 for (ii=0; ii<ninA->cmtArr->len; ii++) {
1362 sprintf(stmp, "comment[%u]", ii)__builtin___sprintf_chk (stmp, 0, __builtin_object_size (stmp
, 2 > 1 ? 1 : 0), "comment[%u]", ii)
;
1363 STRING_COMPARE(cmt[ii], stmp);
1364 }
1365 }
1366 if (ninA->kvpArr->len != ninB->kvpArr->len) {
1367 *differ = ninA->kvpArr->len < ninB->kvpArr->len ? -1 : 1;
1368 if (explain) {
1369 sprintf(explain, "ninA # key/values %u %s ninB # key/values %u",__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA # key/values %u %s ninB # key/values %u"
, ninA->kvpArr->len, *differ < 0 ? "<" : ">", ninB
->kvpArr->len)
1370 ninA->kvpArr->len, *differ < 0 ? "<" : ">", ninB->kvpArr->len)__builtin___sprintf_chk (explain, 0, __builtin_object_size (explain
, 2 > 1 ? 1 : 0), "ninA # key/values %u %s ninB # key/values %u"
, ninA->kvpArr->len, *differ < 0 ? "<" : ">", ninB
->kvpArr->len)
;
1371 }
1372 return 0;
1373 } else {
1374 unsigned int ii;
1375 char stmp[AIR_STRLEN_SMALL(128+1)];
1376 for (ii=0; ii<ninA->kvpArr->len; ii++) {
1377 sprintf(stmp, "key/value key[%u]", ii)__builtin___sprintf_chk (stmp, 0, __builtin_object_size (stmp
, 2 > 1 ? 1 : 0), "key/value key[%u]", ii)
;
1378 STRING_COMPARE(kvp[2*ii + 0], stmp);
1379 sprintf(stmp, "key/value value[%u]", ii)__builtin___sprintf_chk (stmp, 0, __builtin_object_size (stmp
, 2 > 1 ? 1 : 0), "key/value value[%u]", ii)
;
1380 STRING_COMPARE(kvp[2*ii + 1], stmp);
1381 }
1382 }
1383#undef STRING_COMPARE
1384 /* ninA->ptr and ninB->ptr are not to be accessed */
1385
1386 /* if we've gotten this far, all fields were equal */
1387 *differ = 0;
1388 return 0;
1389}
1390
1391/*
1392******** nrrdPPM()
1393**
1394** for making a nrrd suitable for holding PPM data
1395**
1396** "don't mess with peripheral information"
1397*/
1398int
1399nrrdPPM(Nrrd *ppm, size_t sx, size_t sy) {
1400 static const char me[]="nrrdPPM";
1401 char stmp[2][AIR_STRLEN_SMALL(128+1)];
1402
1403 if (nrrdMaybeAlloc_va(ppm, nrrdTypeUChar, 3,
1404 AIR_CAST(size_t, 3)((size_t)(3)), sx, sy)) {
1405 biffAddf(NRRDnrrdBiffKey, "%s: couldn't allocate %s x %s 24-bit image", me,
1406 airSprintSize_t(stmp[0], sx),
1407 airSprintSize_t(stmp[1], sy));
1408 return 1;
1409 }
1410 return 0;
1411}
1412
1413/*
1414******** nrrdPGM()
1415**
1416** for making a nrrd suitable for holding PGM data
1417**
1418** "don't mess with peripheral information"
1419*/
1420int
1421nrrdPGM(Nrrd *pgm, size_t sx, size_t sy) {
1422 static const char me[]="nrrdPGM";
1423 char stmp[2][AIR_STRLEN_SMALL(128+1)];
1424
1425 if (nrrdMaybeAlloc_va(pgm, nrrdTypeUChar, 2,
1426 sx, sy)) {
1427 biffAddf(NRRDnrrdBiffKey, "%s: couldn't allocate %s x %s 8-bit image", me,
1428 airSprintSize_t(stmp[0], sx),
1429 airSprintSize_t(stmp[1], sy));
1430 return 1;
1431 }
1432 return 0;
1433}
1434
1435/* ---- END non-NrrdIO */