Bug Summary

File:src/limn/obj.c
Location:line 242, column 17
Description:Access to field 'lookIdx' results in a dereference of a null pointer (loaded from variable 'part')

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
25#include "limn.h"
26
27/* restricted to this file now since here is the only place its needed */
28typedef union {
29 limnVertex **vert;
30 limnEdge **edge;
31 limnFace **face;
32 limnLook **look;
33 limnPart ***partp;
34 void **v;
35} limnPtrPtrUnion;
36
37int
38limnObjectLookAdd(limnObject *obj) {
39 int lookIdx;
40 limnLook *look;
41
42 lookIdx = airArrayLenIncr(obj->lookArr, 1);
43 look = &(obj->look[lookIdx]);
44 ELL_4V_SET(look->rgba, 1, 1, 1, 1)((look->rgba)[0] = (1), (look->rgba)[1] = (1), (look->
rgba)[2] = (1), (look->rgba)[3] = (1))
;
45 ELL_3V_SET(look->kads, 0.0, 1.0, 0.0)((look->kads)[0] = (0.0), (look->kads)[1] = (1.0), (look
->kads)[2] = (0.0))
;
46 look->spow = 50;
47 return lookIdx;
48}
49
50
51limnObject *
52limnObjectNew(int incr, int doEdges) {
53 limnObject *obj;
54 limnPtrPtrUnion lppu;
55
56 obj = AIR_CALLOC(1, limnObject)(limnObject*)(calloc((1), sizeof(limnObject)));
57 obj->vert = NULL((void*)0);
58 obj->edge = NULL((void*)0);
59 obj->face = NULL((void*)0);
60 obj->faceSort = NULL((void*)0);
61 obj->part = NULL((void*)0);
62 obj->partPool = NULL((void*)0);
63 obj->look = NULL((void*)0);
64
65 /* create all various airArrays */
66 obj->vertArr = airArrayNew((lppu.vert = &(obj->vert), lppu.v),
67 &(obj->vertNum),
68 sizeof(limnVertex), incr);
69 obj->edgeArr = airArrayNew((lppu.edge = &(obj->edge), lppu.v),
70 &(obj->edgeNum),
71 sizeof(limnEdge), incr);
72 obj->faceArr = airArrayNew((lppu.face = &(obj->face), lppu.v),
73 &(obj->faceNum),
74 sizeof(limnFace), incr);
75 obj->partArr = airArrayNew((lppu.partp = &(obj->part), lppu.v),
76 &(obj->partNum),
77 sizeof(limnPart*), incr);
78 obj->partPoolArr = airArrayNew((lppu.partp = &(obj->partPool), lppu.v),
79 &(obj->partPoolNum),
80 sizeof(limnPart*), incr);
81 obj->lookArr = airArrayNew((lppu.look = &(obj->look), lppu.v),
82 &(obj->lookNum),
83 sizeof(limnLook), incr);
84
85 /* create (default) look 0 */
86 limnObjectLookAdd(obj);
87
88 obj->vertSpace = limnSpaceUnknown;
89 obj->setVertexRGBAFromLook = AIR_FALSE0;
90 obj->doEdges = doEdges;
91 obj->incr = incr;
92
93 return obj;
94}
95
96limnPart *
97_limnObjectPartNew(int incr) {
98 limnPart *part;
99 airPtrPtrUnion appu;
100
101 part = AIR_CALLOC(1, limnPart)(limnPart*)(calloc((1), sizeof(limnPart)));
102 if (part) {
103 part->vertIdx = NULL((void*)0);
104 part->edgeIdx = NULL((void*)0);
105 part->faceIdx = NULL((void*)0);
106 part->vertIdxArr = airArrayNew((appu.ui = &(part->vertIdx), appu.v),
107 &(part->vertIdxNum),
108 sizeof(int), incr);
109 part->edgeIdxArr = airArrayNew((appu.ui = &(part->edgeIdx), appu.v),
110 &(part->edgeIdxNum),
111 sizeof(int), incr);
112 part->faceIdxArr = airArrayNew((appu.ui = &(part->faceIdx), appu.v),
113 &(part->faceIdxNum),
114 sizeof(int), incr);
115 }
116 return part;
117}
118
119limnPart *
120_limnObjectPartNix(limnPart *part) {
121
122 if (part) {
123 airArrayNuke(part->vertIdxArr);
124 airArrayNuke(part->edgeIdxArr);
125 airArrayNuke(part->faceIdxArr);
126 airFree(part);
127 }
128 return NULL((void*)0);
129}
130
131void
132_limnObjectFaceEmpty(limnFace *face) {
133
134 if (face) {
135 airFree(face->vertIdx);
136 airFree(face->edgeIdx);
137 }
138 return;
139}
140
141limnObject *
142limnObjectNix(limnObject *obj) {
143 unsigned int partIdx, faceIdx;
144
145 if (obj) {
146 for (partIdx=0; partIdx<obj->partNum; partIdx++) {
147 _limnObjectPartNix(obj->part[partIdx]);
148 }
149 airArrayNuke(obj->partArr);
150 for (partIdx=0; partIdx<obj->partPoolNum; partIdx++) {
151 _limnObjectPartNix(obj->partPool[partIdx]);
152 }
153 airArrayNuke(obj->partPoolArr);
154 for (faceIdx=0; faceIdx<obj->faceNum; faceIdx++) {
155 _limnObjectFaceEmpty(obj->face + faceIdx);
156 }
157 airArrayNuke(obj->faceArr);
158 airArrayNuke(obj->vertArr);
159 airArrayNuke(obj->edgeArr);
160 airFree(obj->faceSort);
161 airArrayNuke(obj->lookArr);
162 airFree(obj);
163 }
164 return NULL((void*)0);
165}
166
167void
168limnObjectEmpty(limnObject *obj) {
169 unsigned int partIdx, faceIdx;
170
171 for (partIdx=0; partIdx<obj->partNum; partIdx++) {
172 _limnObjectPartNix(obj->part[partIdx]);
173 }
174 airArrayLenSet(obj->partArr, 0);
175 for (partIdx=0; partIdx<obj->partPoolNum; partIdx++) {
176 _limnObjectPartNix(obj->partPool[partIdx]);
177 }
178 airArrayLenSet(obj->partPoolArr, 0);
179 for (faceIdx=0; faceIdx<obj->faceNum; faceIdx++) {
180 _limnObjectFaceEmpty(obj->face + faceIdx);
181 }
182 airArrayLenSet(obj->faceArr, 0);
183 airArrayLenSet(obj->vertArr, 0);
184 airArrayLenSet(obj->edgeArr, 0);
185 airFree(obj->faceSort);
186 /* leaves (default) look 0 */
187 airArrayLenSet(obj->lookArr, 1);
188
189 /* don't touch state flags */
190
191 return;
192}
193
194/*
195******** limnObjectPreSet
196**
197** an attempt at pre-allocating everything that will be needed in a
198** limnObject, so that there will be no calloc/memcpy overhead associated
199** with growing any of the airArrays inside
200*/
201int
202limnObjectPreSet(limnObject *obj, unsigned int partNum,
203 unsigned int lookNum, unsigned int vertPerPart,
204 unsigned int edgePerPart, unsigned int facePerPart) {
205 limnPart *part;
206 unsigned int partIdx;
207
208 limnObjectEmpty(obj);
209 airArrayLenPreSet(obj->vertArr, partNum*vertPerPart);
210 airArrayLenPreSet(obj->edgeArr, partNum*edgePerPart);
211 airArrayLenPreSet(obj->faceArr, partNum*facePerPart);
212 airArrayLenPreSet(obj->lookArr, lookNum);
213 airArrayLenPreSet(obj->partArr, partNum);
214
215 airArrayLenSet(obj->partPoolArr, partNum);
216 for (partIdx=0; partIdx<partNum; partIdx++) {
217 part = obj->partPool[partIdx] = _limnObjectPartNew(obj->incr);
218 airArrayLenPreSet(part->vertIdxArr, vertPerPart);
219 airArrayLenPreSet(part->edgeIdxArr, edgePerPart);
220 airArrayLenPreSet(part->faceIdxArr, facePerPart);
221 }
222
223 return 0;
224}
225
226int
227limnObjectPartAdd(limnObject *obj) {
228 unsigned int partIdx;
229 limnPart *part;
230
231 partIdx = airArrayLenIncr(obj->partArr, 1);
232 if (obj->partPoolNum > 0) {
1
Taking false branch
233 part = obj->part[partIdx] = obj->partPool[obj->partPoolNum - 1];
234 airArrayLenIncr(obj->partPoolArr, -1);
235 airArrayLenSet(part->vertIdxArr, 0);
236 airArrayLenSet(part->edgeIdxArr, 0);
237 airArrayLenSet(part->faceIdxArr, 0);
238 } else {
239 /* there are no available parts in the pool */
240 part = obj->part[partIdx] = _limnObjectPartNew(obj->incr);
2
Null pointer value stored to 'part'
241 }
242 part->lookIdx = 0;
3
Access to field 'lookIdx' results in a dereference of a null pointer (loaded from variable 'part')
243 part->depth = AIR_NAN(airFloatQNaN.f);
244 return partIdx;
245}
246
247int
248limnObjectVertexNumPreSet(limnObject *obj, unsigned int partIdx,
249 unsigned int vertNum) {
250 limnPart *part;
251
252 part = obj->part[partIdx];
253 airArrayLenPreSet(obj->vertArr, vertNum);
254 airArrayLenPreSet(part->vertIdxArr, vertNum);
255 return 0;
256}
257
258int
259limnObjectVertexAdd(limnObject *obj, unsigned int partIdx,
260 float x, float y, float z) {
261 limnPart *part;
262 limnVertex *vert;
263 int vertIdx, vertIdxIdx;
264
265 part = obj->part[partIdx];
266 vertIdx = airArrayLenIncr(obj->vertArr, 1);
267 vert = obj->vert + vertIdx;
268 vertIdxIdx = airArrayLenIncr(part->vertIdxArr, 1);
269 part->vertIdx[vertIdxIdx] = vertIdx;
270 ELL_4V_SET(vert->world, x, y, z, 1)((vert->world)[0] = (x), (vert->world)[1] = (y), (vert->
world)[2] = (z), (vert->world)[3] = (1))
;
271 ELL_4V_SET(vert->coord, AIR_NAN, AIR_NAN, AIR_NAN, AIR_NAN)((vert->coord)[0] = ((airFloatQNaN.f)), (vert->coord)[1
] = ((airFloatQNaN.f)), (vert->coord)[2] = ((airFloatQNaN.
f)), (vert->coord)[3] = ((airFloatQNaN.f)))
;
272 /* HEY: this is kind of lame: this information is set in
273 a rather sneaky way, and the setVertexRGBAFromLook is
274 pretty clearly a hack */
275 if (obj->setVertexRGBAFromLook) {
276 ELL_4V_COPY(vert->rgba, obj->look[part->lookIdx].rgba)((vert->rgba)[0] = (obj->look[part->lookIdx].rgba)[0
], (vert->rgba)[1] = (obj->look[part->lookIdx].rgba)
[1], (vert->rgba)[2] = (obj->look[part->lookIdx].rgba
)[2], (vert->rgba)[3] = (obj->look[part->lookIdx].rgba
)[3])
;
277 } else {
278 ELL_4V_SET(vert->rgba, 1, 1, 1, 1)((vert->rgba)[0] = (1), (vert->rgba)[1] = (1), (vert->
rgba)[2] = (1), (vert->rgba)[3] = (1))
;
279 }
280 /* ELL_3V_SET(vert->view, AIR_NAN, AIR_NAN, AIR_NAN); */
281 /* ELL_3V_SET(vert->screen, AIR_NAN, AIR_NAN, AIR_NAN); */
282 ELL_3V_SET(vert->worldNormal, AIR_NAN, AIR_NAN, AIR_NAN)((vert->worldNormal)[0] = ((airFloatQNaN.f)), (vert->worldNormal
)[1] = ((airFloatQNaN.f)), (vert->worldNormal)[2] = ((airFloatQNaN
.f)))
;
283
284 return vertIdx;
285}
286
287int
288limnObjectEdgeAdd(limnObject *obj, unsigned int partIdx,
289 unsigned int lookIdx, unsigned int faceIdx,
290 unsigned int vertIdx0, unsigned int vertIdx1) {
291 int tmp, edgeIdx=-42;
292 unsigned int edgeIdxIdx;
293 limnEdge *edge=NULL((void*)0);
294 limnPart *part;
295
296 part = obj->part[partIdx];
297 if (vertIdx0 > vertIdx1) {
298 ELL_SWAP2(vertIdx0, vertIdx1, tmp)((tmp)=(vertIdx0),(vertIdx0)=(vertIdx1),(vertIdx1)=(tmp));
299 }
300
301 /* do a linear search through this part's existing edges */
302 for (edgeIdxIdx=0; edgeIdxIdx<part->edgeIdxNum; edgeIdxIdx++) {
303 edgeIdx = part->edgeIdx[edgeIdxIdx];
304 edge = obj->edge + edgeIdx;
305 if (edge->vertIdx[0] == vertIdx0
306 && edge->vertIdx[1] == vertIdx1) {
307 break;
308 }
309 }
310 if (edgeIdxIdx == part->edgeIdxNum) {
311 /* edge not found, add it */
312 edgeIdx = airArrayLenIncr(obj->edgeArr, 1);
313 edge = obj->edge + edgeIdx;
314 edgeIdxIdx = airArrayLenIncr(part->edgeIdxArr, 1);
315 part->edgeIdx[edgeIdxIdx] = edgeIdx;
316 edge->vertIdx[0] = vertIdx0;
317 edge->vertIdx[1] = vertIdx1;
318 edge->faceIdx[0] = faceIdx;
319 edge->faceIdx[1] = -1;
320 edge->lookIdx = lookIdx;
321 edge->partIdx = partIdx;
322 edge->type = limnEdgeTypeUnknown;
323 edge->once = AIR_FALSE0;
324 } else {
325 /* edge already exists; "edge", "edgeIdx", and "edgeIdxIdx" are all set */
326 edge->faceIdx[1] = faceIdx;
327 }
328
329 return edgeIdx;
330}
331
332int
333limnObjectFaceNumPreSet(limnObject *obj, unsigned int partIdx,
334 unsigned int faceNum) {
335 limnPart *part;
336
337 part = obj->part[partIdx];
338 airArrayLenPreSet(obj->faceArr, faceNum);
339 airArrayLenPreSet(part->faceIdxArr, faceNum);
340 return 0;
341}
342
343int
344limnObjectFaceAdd(limnObject *obj, unsigned int partIdx,
345 unsigned int lookIdx, unsigned int sideNum,
346 unsigned int *vertIdx) {
347 limnFace *face;
348 limnPart *part;
349 unsigned int faceIdx, faceIdxIdx, sideIdx;
350
351 part = obj->part[partIdx];
352 faceIdx = airArrayLenIncr(obj->faceArr, 1);
353 face = obj->face + faceIdx;
354 faceIdxIdx = airArrayLenIncr(part->faceIdxArr, 1);
355 part->faceIdx[faceIdxIdx] = faceIdx;
356
357 face->vertIdx = AIR_CALLOC(sideNum, unsigned int)(unsigned int*)(calloc((sideNum), sizeof(unsigned int)));
358 face->sideNum = sideNum;
359 if (obj->doEdges) {
360 face->edgeIdx = AIR_CALLOC(sideNum, unsigned int)(unsigned int*)(calloc((sideNum), sizeof(unsigned int)));
361 }
362 for (sideIdx=0; sideIdx<sideNum; sideIdx++) {
363 face->vertIdx[sideIdx] = vertIdx[sideIdx];
364 if (obj->doEdges) {
365 face->edgeIdx[sideIdx] =
366 limnObjectEdgeAdd(obj, partIdx, 0, faceIdx,
367 vertIdx[sideIdx],
368 vertIdx[AIR_MOD((int)sideIdx+1, (int)sideNum)(((int)sideIdx+1)%((int)sideNum) >= 0 ? ((int)sideIdx+1)%(
(int)sideNum) : (int)sideNum + ((int)sideIdx+1)%((int)sideNum
))
]);
369 }
370 }
371 ELL_3V_SET(face->worldNormal, AIR_NAN, AIR_NAN, AIR_NAN)((face->worldNormal)[0] = ((airFloatQNaN.f)), (face->worldNormal
)[1] = ((airFloatQNaN.f)), (face->worldNormal)[2] = ((airFloatQNaN
.f)))
;
372 ELL_3V_SET(face->screenNormal, AIR_NAN, AIR_NAN, AIR_NAN)((face->screenNormal)[0] = ((airFloatQNaN.f)), (face->screenNormal
)[1] = ((airFloatQNaN.f)), (face->screenNormal)[2] = ((airFloatQNaN
.f)))
;
373 /* HEY: its potentially confusing that obj->setVertexRGBAFromLook only
374 has an effect with whole parts, and not individual faces */
375 face->lookIdx = lookIdx;
376 face->partIdx = partIdx;
377 face->visible = AIR_FALSE0;
378 face->depth = AIR_NAN(airFloatQNaN.f);
379
380 return faceIdx;
381}
382