Bug Summary

File:src/unrrdu/jhisto.c
Location:line 156, column 7
Description:Potential leak of memory pointed to by 'npass'

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 "unrrdu.h"
25#include "privateUnrrdu.h"
26
27#define INFO"Create joint histogram of two or more nrrds" "Create joint histogram of two or more nrrds"
28static const char *_unrrdu_jhistoInfoL =
29(INFO"Create joint histogram of two or more nrrds"
30 ". Each axis of the output corresponds to one of the "
31 "input nrrds, and each bin in the output records the "
32 "number of corresponding positions in the inputs with "
33 "a combination of values represented by the coordinates "
34 "of the bin.\n "
35 "* Uses nrrdHistoJoint");
36
37int
38unrrdu_jhistoMain(int argc, const char **argv, const char *me,
39 hestParm *hparm) {
40 hestOpt *opt = NULL((void*)0);
41 char *out, *err;
42 Nrrd **nin, **npass;
43 Nrrd *nout, *nwght;
44 size_t *bin;
45 int type, clamp[NRRD_DIM_MAX16], pret;
46 unsigned int minLen, maxLen, ninLen, binLen, ai, diceax;
47 airArray *mop;
48 double *min, *max;
49 NrrdRange **range;
50
51 hestOptAdd(&opt, "b,bin", "bins0 bins1", airTypeSize_t, 2, -1, &bin, NULL((void*)0),
52 "bins<i> is the number of bins to use along axis i (of joint "
53 "histogram), which represents the values of nin<i> ",
54 &binLen);
55 hestOptAdd(&opt, "w,weight", "nweight", airTypeOther, 1, 1, &nwght, "",
56 "how to weigh contributions to joint histogram. By default "
57 "(not using this option), the increment is one bin count per "
58 "sample, but by giving a nrrd, the value in the nrrd at the "
59 "corresponding location will be the bin count increment ",
60 NULL((void*)0), NULL((void*)0), nrrdHestNrrd);
61 hestOptAdd(&opt, "min,minimum", "min0 min1", airTypeDouble, 2, -1,
62 &min, "nan nan",
63 "min<i> is the low range of values to be quantized along "
64 "axis i; use \"nan\" to represent lowest value present ",
65 &minLen);
66 hestOptAdd(&opt, "max,maximum", "max0 max1", airTypeDouble, 2, -1,
67 &max, "nan nan",
68 "max<i> is the high range of values to be quantized along "
69 "axis i; use \"nan\" to represent highest value present ",
70 &maxLen);
71 OPT_ADD_TYPE(type, "type to use for output (the type used to store hit "hestOptAdd(&opt, "t,type", "type", airTypeEnum, 1, 1, &
(type), "uint", "type to use for output (the type used to store hit "
"counts in the joint histogram). Clamping is done on hit " "counts so that they never overflow a fixed-point type"
, ((void*)0), nrrdType)
72 "counts in the joint histogram). Clamping is done on hit "hestOptAdd(&opt, "t,type", "type", airTypeEnum, 1, 1, &
(type), "uint", "type to use for output (the type used to store hit "
"counts in the joint histogram). Clamping is done on hit " "counts so that they never overflow a fixed-point type"
, ((void*)0), nrrdType)
73 "counts so that they never overflow a fixed-point type",hestOptAdd(&opt, "t,type", "type", airTypeEnum, 1, 1, &
(type), "uint", "type to use for output (the type used to store hit "
"counts in the joint histogram). Clamping is done on hit " "counts so that they never overflow a fixed-point type"
, ((void*)0), nrrdType)
74 "uint")hestOptAdd(&opt, "t,type", "type", airTypeEnum, 1, 1, &
(type), "uint", "type to use for output (the type used to store hit "
"counts in the joint histogram). Clamping is done on hit " "counts so that they never overflow a fixed-point type"
, ((void*)0), nrrdType)
;
75 hestOptAdd(&opt, "i,input", "nin0 [nin1]", airTypeOther, 1, -1, &nin, "-",
76 "list of nrrds (one for each axis of joint histogram), "
77 "or, single nrrd that will be sliced along specified axis.",
78 &ninLen, NULL((void*)0), nrrdHestNrrd);
79 hestOptAdd(&opt, "a,axis", "axis", airTypeUInt, 1, 1, &diceax, "0",
80 "axis to slice along when working with single nrrd. ");
81 OPT_ADD_NOUT(out, "output nrrd")hestOptAdd(&opt, "o,output", "nout", airTypeString, 1, 1,
&(out), "-", "output nrrd")
;
82
83 mop = airMopNew();
84 airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways);
85
86 USAGE(_unrrdu_jhistoInfoL)if (!argc) { hestInfo(__stdoutp, me, (_unrrdu_jhistoInfoL), hparm
); hestUsage(__stdoutp, opt, me, hparm); hestGlossary(__stdoutp
, opt, hparm); airMopError(mop); return 0; }
;
87 PARSE()if ((pret=hestParse(opt, argc, argv, &err, hparm))) { if (
1 == pret || 2 == pret) { if (!(getenv("UNRRDU_QUIET_QUIT") &&
airEndsWith(err, "[nrrd] _nrrdRead: immediately hit EOF" "\n"
))) { fprintf(__stderrp, "%s: %s\n", me, err); free(err); hestUsage
(__stderrp, opt, me, hparm); hestGlossary(__stderrp, opt, hparm
); } airMopError(mop); return 1; } else { exit(1); } }
;
88 airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways);
89
90 if (ninLen == 1) {
1
Assuming 'ninLen' is not equal to 1
2
Taking false branch
91 /* Slice a nrrd on the fly */
92 size_t asize;
93 if (!( diceax <= nin[0]->dim-1 )) {
94 fprintf(stderr__stderrp, "%s: slice axis %u not valid for single %u-D nrrd",
95 me, diceax, nin[0]->dim);
96 airMopError(mop);
97 return 1;
98 }
99 asize = nin[0]->axis[diceax].size;
100 if (asize != binLen) {
101 fprintf(stderr__stderrp,
102 "%s: size (%u) of slice axis %u != # bins given (%u)\n", me,
103 AIR_CAST(unsigned int, asize)((unsigned int)(asize)), diceax,
104 AIR_CAST(unsigned int, binLen)((unsigned int)(binLen)));
105 airMopError(mop);
106 return 1;
107 }
108 /* create buffer for slices */
109 if (!( npass = AIR_CALLOC(binLen, Nrrd*)(Nrrd**)(calloc((binLen), sizeof(Nrrd*))) )) {
110 fprintf(stderr__stderrp, "%s: couldn't allocate nrrd array (size %u)\n",
111 me, binLen);
112 airMopError(mop); return 1;
113 }
114 airMopMem(mop, &npass, airMopAlways);
115 /* slice this nrrd, allocate new nrrds, and store the slices in nin */
116 for (ai=0; ai<binLen; ai++) {
117 /* Allocate each slice nrrd */
118 if (!( npass[ai] = nrrdNew() )) {
119 fprintf(stderr__stderrp, "%s: couldn't allocate npass[%u]\n", me, ai);
120 airMopError(mop); return 1;
121 }
122 airMopAdd(mop, npass[ai], (airMopper)nrrdNuke, airMopAlways);
123 if (nrrdSlice(npass[ai], nin[0], diceax, ai)) {
124 airMopAdd(mop, err = biffGetDone(NRRDnrrdBiffKey), airFree, airMopAlways);
125 fprintf(stderr__stderrp, "%s: error slicing:\n%s", me, err);
126 airMopError(mop); return 1;
127 }
128 }
129 } else {
130 /* we were given multiple nrrds */
131 if (ninLen != binLen) {
3
Taking false branch
132 fprintf(stderr__stderrp,
133 "%s: # input nrrds (%u) != # bin specifications (%u)\n", me,
134 AIR_CAST(unsigned int, ninLen)((unsigned int)(ninLen)), AIR_CAST(unsigned int, binLen)((unsigned int)(binLen)));
135 airMopError(mop);
136 return 1;
137 }
138 /* create buffer for slices (HEY copy and paste) */
139 if (!( npass = AIR_CALLOC(binLen, Nrrd*)(Nrrd**)(calloc((binLen), sizeof(Nrrd*))) )) {
4
Within the expansion of the macro 'AIR_CALLOC':
a
Memory is allocated
5
Assuming 'npass' is not null
6
Taking false branch
140 fprintf(stderr__stderrp, "%s: couldn't allocate nrrd array (size %u)\n",
141 me, binLen);
142 airMopError(mop); return 1;
143 }
144 for (ai=0; ai<binLen; ai++) {
7
Loop condition is true. Entering loop body
8
Assuming 'ai' is >= 'binLen'
9
Loop condition is false. Execution continues on line 148
145 npass[ai] = nin[ai];
146 }
147 }
148 range = AIR_CALLOC(binLen, NrrdRange*)(NrrdRange**)(calloc((binLen), sizeof(NrrdRange*)));
149 airMopAdd(mop, range, airFree, airMopAlways);
150 for (ai=0; ai<binLen; ai++) {
10
Loop condition is true. Entering loop body
11
Loop condition is false. Execution continues on line 154
151 range[ai] = nrrdRangeNew(AIR_NAN(airFloatQNaN.f), AIR_NAN(airFloatQNaN.f));
152 airMopAdd(mop, range[ai], (airMopper)nrrdRangeNix, airMopAlways);
153 }
154 if (2 != minLen || (AIR_EXISTS(min[0])(((int)(!((min[0]) - (min[0]))))) || AIR_EXISTS(min[1])(((int)(!((min[1]) - (min[1]))))))) {
12
Assuming 'minLen' is not equal to 2
155 if (minLen != binLen) {
13
Assuming 'minLen' is not equal to 'binLen'
14
Taking true branch
156 fprintf(stderr__stderrp, "%s: # mins (%d) != # input nrrds (%d)\n", me,
15
Potential leak of memory pointed to by 'npass'
157 minLen, binLen);
158 airMopError(mop); return 1;
159 }
160 for (ai=0; ai<binLen; ai++) {
161 range[ai]->min = min[ai];
162 }
163 }
164 if (2 != maxLen || (AIR_EXISTS(max[0])(((int)(!((max[0]) - (max[0]))))) || AIR_EXISTS(max[1])(((int)(!((max[1]) - (max[1]))))))) {
165 if (maxLen != binLen) {
166 fprintf(stderr__stderrp, "%s: # maxs (%d) != # input nrrds (%d)\n", me,
167 maxLen, binLen);
168 airMopError(mop); return 1;
169 }
170 for (ai=0; ai<binLen; ai++) {
171 range[ai]->max = max[ai];
172 }
173 }
174 for (ai=0; ai<binLen; ai++) {
175 clamp[ai] = 0;
176 }
177
178 nout = nrrdNew();
179 airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways);
180
181 if (nrrdHistoJoint(nout, (const Nrrd*const*)npass,
182 (const NrrdRange*const*)range,
183 binLen, nwght, bin, type, clamp)) {
184 airMopAdd(mop, err = biffGetDone(NRRDnrrdBiffKey), airFree, airMopAlways);
185 fprintf(stderr__stderrp, "%s: error doing joint histogram:\n%s", me, err);
186 airMopError(mop);
187 return 1;
188 }
189
190 SAVE(out, nout, NULL)if (nrrdSave((out), (nout), (((void*)0)))) { airMopAdd(mop, err
= biffGetDone(nrrdBiffKey), airFree, airMopAlways); fprintf(
__stderrp, "%s: error saving nrrd to \"%s\":\n%s\n", me, (out
), err); airMopError(mop); return 1; }
;
191
192 airMopOkay(mop);
193 return 0;
194}
195
196UNRRDU_CMD(jhisto, INFO)unrrduCmd unrrdu_jhistoCmd = { "jhisto", "Create joint histogram of two or more nrrds"
, unrrdu_jhistoMain, 0 }
;