File: | src/nrrd/cc.c |
Location: | line 339, column 3 |
Description: | Value stored to 'ret' is never read |
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 | /* |
28 | ** learned: if you have globals, such as _nrrdCC_verb, which are |
29 | ** defined and declared here, but which are NOT initialized, then |
30 | ** C++ apps which are linking against Teem will have problems!!! |
31 | ** This was first seen on the mac. |
32 | */ |
33 | int _nrrdCC_verb = 0; |
34 | int _nrrdCC_EqvIncr = 10000; /* HEY: this has to be big so that ccfind is not |
35 | stuck constantly re-allocating the eqv array. |
36 | This is will be one of the best places to |
37 | test the new multiplicative reallocation |
38 | strategy, planned for Teem 2.0 */ |
39 | |
40 | int |
41 | _nrrdCCFind_1(Nrrd *nout, unsigned int *numid, const Nrrd *nin) { |
42 | /* static const char me[]="_nrrdCCFind_1"; */ |
43 | unsigned int sx, I, id, lval, val, *out, (*lup)(const void *, size_t); |
44 | |
45 | lup = nrrdUILookup[nin->type]; |
46 | out = AIR_CAST(unsigned int*, nout->data)((unsigned int*)(nout->data)); |
47 | out[0] = id = 0; |
48 | *numid = 1; |
49 | |
50 | sx = AIR_CAST(unsigned int, nin->axis[0].size)((unsigned int)(nin->axis[0].size)); |
51 | lval = lup(nin->data, 0); |
52 | for (I=1; I<sx; I++) { |
53 | val = lup(nin->data, I); |
54 | if (lval != val) { |
55 | id++; |
56 | (*numid)++; |
57 | } |
58 | out[I] = id; |
59 | lval = val; |
60 | } |
61 | |
62 | return 0; |
63 | } |
64 | |
65 | /* |
66 | ** layout of value (pvl) and index (pid) cache: |
67 | ** |
68 | ** 2 3 4 --> X |
69 | ** 1 . . oddly, index 0 is never used |
70 | ** . . . |
71 | ** | |
72 | ** v Y |
73 | */ |
74 | int |
75 | _nrrdCCFind_2(Nrrd *nout, unsigned int *numid, airArray *eqvArr, |
76 | const Nrrd *nin, unsigned int conny) { |
77 | static const char me[]="_nrrdCCFind_2"; |
78 | double vl=0, pvl[5]={0,0,0,0,0}; |
79 | unsigned int id, pid[5]={0,0,0,0,0}, (*lup)(const void *, size_t), *out; |
80 | unsigned int p, x, y, sx, sy; |
81 | |
82 | id = 0; /* sssh! compiler warnings */ |
83 | lup = nrrdUILookup[nin->type]; |
84 | out = AIR_CAST(unsigned int*, nout->data)((unsigned int*)(nout->data)); |
85 | sx = AIR_CAST(unsigned int, nin->axis[0].size)((unsigned int)(nin->axis[0].size)); |
86 | sy = AIR_CAST(unsigned int, nin->axis[1].size)((unsigned int)(nin->axis[1].size)); |
87 | #define GETV_2(x,y)((((0) <= (((int)(x))) && (((int)(x))) <= (((int )(sx-1)))) && ((0) <= (((int)(y))) && (((int )(y))) <= (((int)(sy-1))))) ? lup(nin->data, (x) + sx*( y)) : 0.5) ((AIR_IN_CL(0, AIR_CAST(int, x), AIR_CAST(int, sx-1))((0) <= (((int)(x))) && (((int)(x))) <= (((int) (sx-1)))) \ |
88 | && AIR_IN_CL(0, AIR_CAST(int, y), AIR_CAST(int, sy-1))((0) <= (((int)(y))) && (((int)(y))) <= (((int) (sy-1))))) \ |
89 | ? lup(nin->data, (x) + sx*(y)) \ |
90 | : 0.5) /* value that can't come from an array of uints */ |
91 | #define GETI_2(x,y)((((0) <= (((int)(x))) && (((int)(x))) <= (((int )(sx-1)))) && ((0) <= (((int)(y))) && (((int )(y))) <= (((int)(sy-1))))) ? out[(x) + sx*(y)] : ((unsigned int)(-1))) ((AIR_IN_CL(0, AIR_CAST(int, x), AIR_CAST(int, sx-1))((0) <= (((int)(x))) && (((int)(x))) <= (((int) (sx-1)))) \ |
92 | && AIR_IN_CL(0, AIR_CAST(int, y), AIR_CAST(int, sy-1))((0) <= (((int)(y))) && (((int)(y))) <= (((int) (sy-1))))) \ |
93 | ? out[(x) + sx*(y)] \ |
94 | : AIR_CAST(unsigned int, -1)((unsigned int)(-1))) /* CC index (probably!) |
95 | never assigned */ |
96 | |
97 | *numid = 0; |
98 | for (y=0; y<sy; y++) { |
99 | for (x=0; x<sx; x++) { |
100 | if (_nrrdCC_verb) { |
101 | fprintf(stderr__stderrp, "%s(%d,%d) -----------\n", me, x, y); |
102 | } |
103 | if (!x) { |
104 | pvl[1] = GETV_2(-1, y)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y))) && ( ((int)(y))) <= (((int)(sy-1))))) ? lup(nin->data, (-1) + sx*(y)) : 0.5); pid[1] = GETI_2(-1, y)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y))) && ( ((int)(y))) <= (((int)(sy-1))))) ? out[(-1) + sx*(y)] : (( unsigned int)(-1))); |
105 | pvl[2] = GETV_2(-1, y-1)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1))))) ? lup(nin->data, ( -1) + sx*(y-1)) : 0.5); pid[2] = GETI_2(-1, y-1)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1))))) ? out[(-1) + sx*(y-1) ] : ((unsigned int)(-1))); |
106 | pvl[3] = GETV_2(0, y-1)((((0) <= (((int)(0))) && (((int)(0))) <= (((int )(sx-1)))) && ((0) <= (((int)(y-1))) && (( (int)(y-1))) <= (((int)(sy-1))))) ? lup(nin->data, (0) + sx*(y-1)) : 0.5); pid[3] = GETI_2(0, y-1)((((0) <= (((int)(0))) && (((int)(0))) <= (((int )(sx-1)))) && ((0) <= (((int)(y-1))) && (( (int)(y-1))) <= (((int)(sy-1))))) ? out[(0) + sx*(y-1)] : ( (unsigned int)(-1))); |
107 | |
108 | } else { |
109 | pvl[1] = vl; pid[1] = id; |
110 | pvl[2] = pvl[3]; pid[2] = pid[3]; |
111 | pvl[3] = pvl[4]; pid[3] = pid[4]; |
112 | } |
113 | pvl[4] = GETV_2(x+1, y-1)((((0) <= (((int)(x+1))) && (((int)(x+1))) <= ( ((int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1))))) ? lup(nin->data, ( x+1) + sx*(y-1)) : 0.5); pid[4] = GETI_2(x+1, y-1)((((0) <= (((int)(x+1))) && (((int)(x+1))) <= ( ((int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1))))) ? out[(x+1) + sx*(y-1 )] : ((unsigned int)(-1))); |
114 | vl = GETV_2(x, y)((((0) <= (((int)(x))) && (((int)(x))) <= (((int )(sx-1)))) && ((0) <= (((int)(y))) && (((int )(y))) <= (((int)(sy-1))))) ? lup(nin->data, (x) + sx*( y)) : 0.5); |
115 | p = 0; |
116 | if (vl == pvl[1]) { |
117 | id = pid[p=1]; |
118 | } |
119 | #define TEST(P)if (vl == pvl[(P)]) { if (p) { if (id != pid[(P)]) { airEqvAdd (eqvArr, pid[(P)], id); } } else { id = pid[p=(P)]; } } \ |
120 | if (vl == pvl[(P)]) { \ |
121 | if (p) { /* we already had a value match */ \ |
122 | if (id != pid[(P)]) { \ |
123 | airEqvAdd(eqvArr, pid[(P)], id); \ |
124 | } \ |
125 | } else { \ |
126 | id = pid[p=(P)]; \ |
127 | } \ |
128 | } |
129 | TEST(3)if (vl == pvl[(3)]) { if (p) { if (id != pid[(3)]) { airEqvAdd (eqvArr, pid[(3)], id); } } else { id = pid[p=(3)]; } }; |
130 | if (2 == conny) { |
131 | TEST(2)if (vl == pvl[(2)]) { if (p) { if (id != pid[(2)]) { airEqvAdd (eqvArr, pid[(2)], id); } } else { id = pid[p=(2)]; } }; |
132 | TEST(4)if (vl == pvl[(4)]) { if (p) { if (id != pid[(4)]) { airEqvAdd (eqvArr, pid[(4)], id); } } else { id = pid[p=(4)]; } }; |
133 | } |
134 | if (!p) { |
135 | /* didn't match anything previous */ |
136 | id = *numid; |
137 | (*numid)++; |
138 | } |
139 | if (_nrrdCC_verb) { |
140 | fprintf(stderr__stderrp, "%s: pvl: %g %g %g %g (vl = %g)\n", me, |
141 | pvl[1], pvl[2], pvl[3], pvl[4], vl); |
142 | fprintf(stderr__stderrp, " pid: %d %d %d %d\n", |
143 | pid[1], pid[2], pid[3], pid[4]); |
144 | fprintf(stderr__stderrp, " --> p = %d, id = %d, *numid = %d\n", |
145 | p, id, *numid); |
146 | } |
147 | out[x + sx*y] = id; |
148 | } |
149 | } |
150 | |
151 | return 0; |
152 | } |
153 | |
154 | /* |
155 | ** |
156 | ** 5 6 7 --> X |
157 | ** 8 9 10 |
158 | ** 11 12 13 |
159 | ** | |
160 | ** v Y |
161 | ** 2 3 4 |
162 | ** / 1 . . again, 0 index never used, for reasons forgotten |
163 | ** Z . . . |
164 | */ |
165 | int |
166 | _nrrdCCFind_3(Nrrd *nout, unsigned int *numid, airArray *eqvArr, |
167 | const Nrrd *nin, unsigned int conny) { |
168 | /* static const char me[]="_nrrdCCFind_3" ; */ |
169 | double pvl[14]={0,0,0,0,0,0,0,0,0,0,0,0,0,0}, vl=0; |
170 | unsigned int id, *out, (*lup)(const void *, size_t), |
171 | pid[14]={0,0,0,0,0,0,0,0,0,0,0,0,0,0}; |
172 | unsigned int p, x, y, z, sx, sy, sz; |
173 | |
174 | id = 0; /* sssh! compiler warnings */ |
175 | lup = nrrdUILookup[nin->type]; |
176 | out = AIR_CAST(unsigned int*, nout->data)((unsigned int*)(nout->data)); |
177 | sx = AIR_CAST(unsigned int, nin->axis[0].size)((unsigned int)(nin->axis[0].size)); |
178 | sy = AIR_CAST(unsigned int, nin->axis[1].size)((unsigned int)(nin->axis[1].size)); |
179 | sz = AIR_CAST(unsigned int, nin->axis[2].size)((unsigned int)(nin->axis[2].size)); |
180 | #define GETV_3(x,y,z)((((0) <= (((int)(x))) && (((int)(x))) <= (((int )(sx-1)))) && ((0) <= (((int)(y))) && (((int )(y))) <= (((int)(sy-1)))) && ((0) <= (((int)(z ))) && (((int)(z))) <= (((int)(sz-1))))) ? lup(nin ->data, (x) + sx*((y) + sy*(z))) : 0.5) ((AIR_IN_CL(0, AIR_CAST(int, x), AIR_CAST(int, sx-1))((0) <= (((int)(x))) && (((int)(x))) <= (((int) (sx-1)))) \ |
181 | && AIR_IN_CL(0, AIR_CAST(int, y), AIR_CAST(int, sy-1))((0) <= (((int)(y))) && (((int)(y))) <= (((int) (sy-1)))) \ |
182 | && AIR_IN_CL(0, AIR_CAST(int, z), AIR_CAST(int, sz-1))((0) <= (((int)(z))) && (((int)(z))) <= (((int) (sz-1)))))\ |
183 | ? lup(nin->data, (x) + sx*((y) + sy*(z))) \ |
184 | : 0.5) |
185 | #define GETI_3(x,y,z)((((0) <= (((int)(x))) && (((int)(x))) <= (((int )(sx-1)))) && ((0) <= (((int)(y))) && (((int )(y))) <= (((int)(sy-1)))) && ((0) <= (((int)(z ))) && (((int)(z))) <= (((int)(sz-1))))) ? out[(x) + sx*((y) + sy*(z))] : ((unsigned int)(-1))) ((AIR_IN_CL(0, AIR_CAST(int, x), AIR_CAST(int, sx-1))((0) <= (((int)(x))) && (((int)(x))) <= (((int) (sx-1)))) \ |
186 | && AIR_IN_CL(0, AIR_CAST(int, y), AIR_CAST(int, sy-1))((0) <= (((int)(y))) && (((int)(y))) <= (((int) (sy-1)))) \ |
187 | && AIR_IN_CL(0, AIR_CAST(int, z), AIR_CAST(int, sz-1))((0) <= (((int)(z))) && (((int)(z))) <= (((int) (sz-1)))))\ |
188 | ? out[(x) + sx*((y) + sy*(z))] \ |
189 | : AIR_CAST(unsigned int, -1)((unsigned int)(-1))) |
190 | |
191 | *numid = 0; |
192 | for (z=0; z<sz; z++) { |
193 | for (y=0; y<sy; y++) { |
194 | for (x=0; x<sx; x++) { |
195 | if (!x) { |
196 | pvl[ 1] = GETV_3( -1, y, z)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y))) && ( ((int)(y))) <= (((int)(sy-1)))) && ((0) <= (((int )(z))) && (((int)(z))) <= (((int)(sz-1))))) ? lup( nin->data, (-1) + sx*((y) + sy*(z))) : 0.5); pid[ 1] = GETI_3( -1, y, z)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y))) && ( ((int)(y))) <= (((int)(sy-1)))) && ((0) <= (((int )(z))) && (((int)(z))) <= (((int)(sz-1))))) ? out[ (-1) + sx*((y) + sy*(z))] : ((unsigned int)(-1))); |
197 | pvl[ 2] = GETV_3( -1, y-1, z)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z))) && (((int)(z))) <= (((int)(sz-1))))) ? lup(nin->data, (-1) + sx*((y-1) + sy*(z))) : 0.5); pid[ 2] = GETI_3( -1, y-1, z)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z))) && (((int)(z))) <= (((int)(sz-1))))) ? out[(-1) + sx*((y-1) + sy*(z))] : ((unsigned int)(-1))); |
198 | pvl[ 3] = GETV_3( 0, y-1, z)((((0) <= (((int)(0))) && (((int)(0))) <= (((int )(sx-1)))) && ((0) <= (((int)(y-1))) && (( (int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ((( int)(z))) && (((int)(z))) <= (((int)(sz-1))))) ? lup (nin->data, (0) + sx*((y-1) + sy*(z))) : 0.5); pid[ 3] = GETI_3( 0, y-1, z)((((0) <= (((int)(0))) && (((int)(0))) <= (((int )(sx-1)))) && ((0) <= (((int)(y-1))) && (( (int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ((( int)(z))) && (((int)(z))) <= (((int)(sz-1))))) ? out [(0) + sx*((y-1) + sy*(z))] : ((unsigned int)(-1))); |
199 | pvl[ 5] = GETV_3( -1, y-1, z-1)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))) )) ? lup(nin->data, (-1) + sx*((y-1) + sy*(z-1))) : 0.5); pid[ 5] = GETI_3( -1, y-1, z-1)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))) )) ? out[(-1) + sx*((y-1) + sy*(z-1))] : ((unsigned int)(-1)) ); |
200 | pvl[ 8] = GETV_3( -1, y, z-1)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y))) && ( ((int)(y))) <= (((int)(sy-1)))) && ((0) <= (((int )(z-1))) && (((int)(z-1))) <= (((int)(sz-1))))) ? lup (nin->data, (-1) + sx*((y) + sy*(z-1))) : 0.5); pid[ 8] = GETI_3( -1, y, z-1)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y))) && ( ((int)(y))) <= (((int)(sy-1)))) && ((0) <= (((int )(z-1))) && (((int)(z-1))) <= (((int)(sz-1))))) ? out [(-1) + sx*((y) + sy*(z-1))] : ((unsigned int)(-1))); |
201 | pvl[11] = GETV_3( -1, y+1, z-1)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y+1))) && (((int)(y+1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))) )) ? lup(nin->data, (-1) + sx*((y+1) + sy*(z-1))) : 0.5); pid[11] = GETI_3( -1, y+1, z-1)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y+1))) && (((int)(y+1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))) )) ? out[(-1) + sx*((y+1) + sy*(z-1))] : ((unsigned int)(-1)) ); |
202 | pvl[ 6] = GETV_3( 0, y-1, z-1)((((0) <= (((int)(0))) && (((int)(0))) <= (((int )(sx-1)))) && ((0) <= (((int)(y-1))) && (( (int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ((( int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))))) ? lup(nin->data, (0) + sx*((y-1) + sy*(z-1))) : 0.5); pid[ 6] = GETI_3( 0, y-1, z-1)((((0) <= (((int)(0))) && (((int)(0))) <= (((int )(sx-1)))) && ((0) <= (((int)(y-1))) && (( (int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ((( int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))))) ? out[(0) + sx*((y-1) + sy*(z-1))] : ((unsigned int)(-1))); |
203 | pvl[ 9] = GETV_3( 0, y, z-1)((((0) <= (((int)(0))) && (((int)(0))) <= (((int )(sx-1)))) && ((0) <= (((int)(y))) && (((int )(y))) <= (((int)(sy-1)))) && ((0) <= (((int)(z -1))) && (((int)(z-1))) <= (((int)(sz-1))))) ? lup (nin->data, (0) + sx*((y) + sy*(z-1))) : 0.5); pid[ 9] = GETI_3( 0, y, z-1)((((0) <= (((int)(0))) && (((int)(0))) <= (((int )(sx-1)))) && ((0) <= (((int)(y))) && (((int )(y))) <= (((int)(sy-1)))) && ((0) <= (((int)(z -1))) && (((int)(z-1))) <= (((int)(sz-1))))) ? out [(0) + sx*((y) + sy*(z-1))] : ((unsigned int)(-1))); |
204 | pvl[12] = GETV_3( 0, y+1, z-1)((((0) <= (((int)(0))) && (((int)(0))) <= (((int )(sx-1)))) && ((0) <= (((int)(y+1))) && (( (int)(y+1))) <= (((int)(sy-1)))) && ((0) <= ((( int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))))) ? lup(nin->data, (0) + sx*((y+1) + sy*(z-1))) : 0.5); pid[12] = GETI_3( 0, y+1, z-1)((((0) <= (((int)(0))) && (((int)(0))) <= (((int )(sx-1)))) && ((0) <= (((int)(y+1))) && (( (int)(y+1))) <= (((int)(sy-1)))) && ((0) <= ((( int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))))) ? out[(0) + sx*((y+1) + sy*(z-1))] : ((unsigned int)(-1))); |
205 | } else { |
206 | pvl[ 1] = vl; pid[ 1] = id; |
207 | pvl[ 2] = pvl[ 3]; pid[ 2] = pid[ 3]; |
208 | pvl[ 3] = pvl[ 4]; pid[ 3] = pid[ 4]; |
209 | pvl[ 5] = pvl[ 6]; pid[ 5] = pid[ 6]; |
210 | pvl[ 8] = pvl[ 9]; pid[ 8] = pid[ 9]; |
211 | pvl[11] = pvl[12]; pid[11] = pid[12]; |
212 | pvl[ 6] = pvl[ 7]; pid[ 6] = pid[ 7]; |
213 | pvl[ 9] = pvl[10]; pid[ 9] = pid[10]; |
214 | pvl[12] = pvl[13]; pid[12] = pid[13]; |
215 | } |
216 | pvl[ 4] = GETV_3(x+1, y-1, z)((((0) <= (((int)(x+1))) && (((int)(x+1))) <= ( ((int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z))) && (((int)(z))) <= (((int)(sz-1))))) ? lup(nin->data, (x+1) + sx*((y-1) + sy*(z))) : 0.5); pid[ 4] = GETI_3(x+1, y-1, z)((((0) <= (((int)(x+1))) && (((int)(x+1))) <= ( ((int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z))) && (((int)(z))) <= (((int)(sz-1))))) ? out[(x+1) + sx*((y-1) + sy*(z))] : ((unsigned int)(-1))); |
217 | pvl[ 7] = GETV_3(x+1, y-1, z-1)((((0) <= (((int)(x+1))) && (((int)(x+1))) <= ( ((int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))) )) ? lup(nin->data, (x+1) + sx*((y-1) + sy*(z-1))) : 0.5); pid[ 7] = GETI_3(x+1, y-1, z-1)((((0) <= (((int)(x+1))) && (((int)(x+1))) <= ( ((int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))) )) ? out[(x+1) + sx*((y-1) + sy*(z-1))] : ((unsigned int)(-1) )); |
218 | pvl[10] = GETV_3(x+1, y, z-1)((((0) <= (((int)(x+1))) && (((int)(x+1))) <= ( ((int)(sx-1)))) && ((0) <= (((int)(y))) && (((int)(y))) <= (((int)(sy-1)))) && ((0) <= (( (int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1)))) ) ? lup(nin->data, (x+1) + sx*((y) + sy*(z-1))) : 0.5); pid[10] = GETI_3(x+1, y, z-1)((((0) <= (((int)(x+1))) && (((int)(x+1))) <= ( ((int)(sx-1)))) && ((0) <= (((int)(y))) && (((int)(y))) <= (((int)(sy-1)))) && ((0) <= (( (int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1)))) ) ? out[(x+1) + sx*((y) + sy*(z-1))] : ((unsigned int)(-1))); |
219 | pvl[13] = GETV_3(x+1, y+1, z-1)((((0) <= (((int)(x+1))) && (((int)(x+1))) <= ( ((int)(sx-1)))) && ((0) <= (((int)(y+1))) && (((int)(y+1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))) )) ? lup(nin->data, (x+1) + sx*((y+1) + sy*(z-1))) : 0.5); pid[13] = GETI_3(x+1, y+1, z-1)((((0) <= (((int)(x+1))) && (((int)(x+1))) <= ( ((int)(sx-1)))) && ((0) <= (((int)(y+1))) && (((int)(y+1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))) )) ? out[(x+1) + sx*((y+1) + sy*(z-1))] : ((unsigned int)(-1) )); |
220 | vl = GETV_3(x, y, z)((((0) <= (((int)(x))) && (((int)(x))) <= (((int )(sx-1)))) && ((0) <= (((int)(y))) && (((int )(y))) <= (((int)(sy-1)))) && ((0) <= (((int)(z ))) && (((int)(z))) <= (((int)(sz-1))))) ? lup(nin ->data, (x) + sx*((y) + sy*(z))) : 0.5); |
221 | p = 0; |
222 | if (vl == pvl[1]) { |
223 | id = pid[p=1]; |
224 | } |
225 | TEST(3)if (vl == pvl[(3)]) { if (p) { if (id != pid[(3)]) { airEqvAdd (eqvArr, pid[(3)], id); } } else { id = pid[p=(3)]; } }; |
226 | TEST(9)if (vl == pvl[(9)]) { if (p) { if (id != pid[(9)]) { airEqvAdd (eqvArr, pid[(9)], id); } } else { id = pid[p=(9)]; } }; |
227 | if (2 <= conny) { |
228 | TEST(2)if (vl == pvl[(2)]) { if (p) { if (id != pid[(2)]) { airEqvAdd (eqvArr, pid[(2)], id); } } else { id = pid[p=(2)]; } }; TEST(4)if (vl == pvl[(4)]) { if (p) { if (id != pid[(4)]) { airEqvAdd (eqvArr, pid[(4)], id); } } else { id = pid[p=(4)]; } }; |
229 | TEST(6)if (vl == pvl[(6)]) { if (p) { if (id != pid[(6)]) { airEqvAdd (eqvArr, pid[(6)], id); } } else { id = pid[p=(6)]; } }; TEST(8)if (vl == pvl[(8)]) { if (p) { if (id != pid[(8)]) { airEqvAdd (eqvArr, pid[(8)], id); } } else { id = pid[p=(8)]; } }; TEST(10)if (vl == pvl[(10)]) { if (p) { if (id != pid[(10)]) { airEqvAdd (eqvArr, pid[(10)], id); } } else { id = pid[p=(10)]; } }; TEST(12)if (vl == pvl[(12)]) { if (p) { if (id != pid[(12)]) { airEqvAdd (eqvArr, pid[(12)], id); } } else { id = pid[p=(12)]; } }; |
230 | if (3 == conny) { |
231 | TEST(5)if (vl == pvl[(5)]) { if (p) { if (id != pid[(5)]) { airEqvAdd (eqvArr, pid[(5)], id); } } else { id = pid[p=(5)]; } }; TEST(7)if (vl == pvl[(7)]) { if (p) { if (id != pid[(7)]) { airEqvAdd (eqvArr, pid[(7)], id); } } else { id = pid[p=(7)]; } }; TEST(11)if (vl == pvl[(11)]) { if (p) { if (id != pid[(11)]) { airEqvAdd (eqvArr, pid[(11)], id); } } else { id = pid[p=(11)]; } }; TEST(13)if (vl == pvl[(13)]) { if (p) { if (id != pid[(13)]) { airEqvAdd (eqvArr, pid[(13)], id); } } else { id = pid[p=(13)]; } }; |
232 | } |
233 | } |
234 | if (!p) { |
235 | /* didn't match anything previous */ |
236 | id = *numid; |
237 | (*numid)++; |
238 | } |
239 | out[x + sx*(y + sy*z)] = id; |
240 | } |
241 | } |
242 | } |
243 | |
244 | return 0; |
245 | } |
246 | |
247 | int |
248 | _nrrdCCFind_N(Nrrd *nout, unsigned int *numid, airArray *eqvArr, |
249 | const Nrrd *nin, unsigned int conny) { |
250 | static const char me[]="_nrrdCCFind_N"; |
251 | |
252 | AIR_UNUSED(nout)(void)(nout); |
253 | AIR_UNUSED(numid)(void)(numid); |
254 | AIR_UNUSED(eqvArr)(void)(eqvArr); |
255 | AIR_UNUSED(nin)(void)(nin); |
256 | AIR_UNUSED(conny)(void)(conny); |
257 | biffAddf(NRRDnrrdBiffKey, "%s: sorry, not implemented yet", me); |
258 | return 1; |
259 | } |
260 | |
261 | /* |
262 | ******** nrrdCCFind |
263 | ** |
264 | ** finds connected components (CCs) in given integral type nrrd "nin", |
265 | ** according to connectivity "conny", putting the results in "nout". |
266 | ** The "type" argument controls what type the output will be. If |
267 | ** type == nrrdTypeDefault, the type used will be the smallest that |
268 | ** can contain the CC id values. Otherwise, the specified type "type" |
269 | ** will be used, assuming that it is large enough to hold the CC ids. |
270 | ** |
271 | ** "conny": the number of coordinates that need to varied together in |
272 | ** order to reach all the samples that are to consitute the neighborhood |
273 | ** around a sample. For 2-D, conny==1 specifies the 4 edge-connected |
274 | ** pixels, and 2 specifies the 8 edge- and corner-connected. |
275 | ** |
276 | ** The caller can get a record of the values in each CC by passing a |
277 | ** non-NULL nval, which will be allocated to an array of the same type |
278 | ** as nin, so that nval->data[I] is the value in nin inside CC #I. |
279 | */ |
280 | int |
281 | nrrdCCFind(Nrrd *nout, Nrrd **nvalP, const Nrrd *nin, int type, |
282 | unsigned int conny) { |
283 | static const char me[]="nrrdCCFind", func[]="ccfind"; |
284 | Nrrd *nfpid; /* first-pass IDs */ |
285 | airArray *mop, *eqvArr; |
286 | unsigned int *fpid, numid, numsettleid, *map, |
287 | (*lup)(const void *, size_t), (*ins)(void *, size_t, unsigned int); |
288 | int ret; |
289 | size_t I, NN; |
290 | void *val; |
291 | |
292 | if (!(nout && nin)) { |
293 | /* NULL nvalP okay */ |
294 | biffAddf(NRRDnrrdBiffKey, "%s: got NULL pointer", me); |
295 | return 1; |
296 | } |
297 | if (nout == nin) { |
298 | biffAddf(NRRDnrrdBiffKey, "%s: nout == nin disallowed", me); |
299 | return 1; |
300 | } |
301 | if (!( nrrdTypeIsIntegral[nin->type] |
302 | && nrrdTypeIsUnsigned[nin->type] |
303 | && nrrdTypeSize[nin->type] <= 4 )) { |
304 | biffAddf(NRRDnrrdBiffKey, "%s: can only find connected components in " |
305 | "1, 2, or 4 byte unsigned integral values (not %s)", |
306 | me, airEnumStr(nrrdType, nin->type)); |
307 | return 1; |
308 | } |
309 | if (nrrdTypeDefault != type) { |
310 | if (!( AIR_IN_OP(nrrdTypeUnknown, type, nrrdTypeLast)((nrrdTypeUnknown) < (type) && (type) < (nrrdTypeLast )) )) { |
311 | biffAddf(NRRDnrrdBiffKey, "%s: got invalid target type %d", me, type); |
312 | return 1; |
313 | } |
314 | if (!( nrrdTypeIsIntegral[type] |
315 | && nrrdTypeIsUnsigned[nin->type] |
316 | && nrrdTypeSize[type] <= 4 )) { |
317 | biffAddf(NRRDnrrdBiffKey, |
318 | "%s: can only save connected components to 1, 2, or 4 byte " |
319 | "unsigned integral values (not %s)", |
320 | me, airEnumStr(nrrdType, type)); |
321 | return 1; |
322 | } |
323 | } |
324 | if (!( conny <= nin->dim )) { |
325 | biffAddf(NRRDnrrdBiffKey, "%s: connectivity value must be in [1..%d] for %d-D " |
326 | "data (not %d)", me, nin->dim, nin->dim, conny); |
327 | return 1; |
328 | } |
329 | if (nrrdConvert(nfpid=nrrdNew(), nin, nrrdTypeUInt)) { |
330 | biffAddf(NRRDnrrdBiffKey, "%s: couldn't allocate fpid %s array to match input size", |
331 | me, airEnumStr(nrrdType, nrrdTypeUInt)); |
332 | return 1; |
333 | } |
334 | |
335 | mop = airMopNew(); |
336 | airMopAdd(mop, nfpid, (airMopper)nrrdNuke, airMopAlways); |
337 | eqvArr = airArrayNew(NULL((void*)0), NULL((void*)0), 2*sizeof(unsigned int), _nrrdCC_EqvIncr); |
338 | airMopAdd(mop, eqvArr, (airMopper)airArrayNuke, airMopAlways); |
339 | ret = 0; |
Value stored to 'ret' is never read | |
340 | switch(nin->dim) { |
341 | case 1: |
342 | ret = _nrrdCCFind_1(nfpid, &numid, nin); |
343 | break; |
344 | case 2: |
345 | ret = _nrrdCCFind_2(nfpid, &numid, eqvArr, nin, conny); |
346 | break; |
347 | case 3: |
348 | ret = _nrrdCCFind_3(nfpid, &numid, eqvArr, nin, conny); |
349 | break; |
350 | default: |
351 | ret = _nrrdCCFind_N(nfpid, &numid, eqvArr, nin, conny); |
352 | break; |
353 | } |
354 | if (ret) { |
355 | biffAddf(NRRDnrrdBiffKey, "%s: initial pass failed", me); |
356 | airMopError(mop); return 1; |
357 | } |
358 | |
359 | map = AIR_MALLOC(numid, unsigned int)(unsigned int*)(malloc((numid)*sizeof(unsigned int))); |
360 | airMopAdd(mop, map, airFree, airMopAlways); |
361 | numsettleid = airEqvMap(eqvArr, map, numid); |
362 | /* convert fpid values to final id values */ |
363 | fpid = (unsigned int*)(nfpid->data); |
364 | NN = nrrdElementNumber(nfpid); |
365 | for (I=0; I<NN; I++) { |
366 | fpid[I] = map[fpid[I]]; |
367 | } |
368 | if (nvalP) { |
369 | if (!(*nvalP)) { |
370 | *nvalP = nrrdNew(); |
371 | } |
372 | if (nrrdMaybeAlloc_va(*nvalP, nin->type, 1, |
373 | AIR_CAST(size_t, numsettleid)((size_t)(numsettleid)))) { |
374 | biffAddf(NRRDnrrdBiffKey, "%s: couldn't allocate output value list", me); |
375 | airMopError(mop); return 1; |
376 | } |
377 | airMopAdd(mop, nvalP, (airMopper)airSetNull, airMopOnError); |
378 | airMopAdd(mop, *nvalP, (airMopper)nrrdNuke, airMopOnError); |
379 | val = (*nvalP)->data; |
380 | lup = nrrdUILookup[nin->type]; |
381 | ins = nrrdUIInsert[nin->type]; |
382 | /* I'm not sure if its more work to do all the redundant assignments |
383 | or to check whether or not to do them */ |
384 | for (I=0; I<NN; I++) { |
385 | ins(val, fpid[I], lup(nin->data, I)); |
386 | } |
387 | } |
388 | |
389 | if (nrrdTypeDefault != type) { |
390 | if (numsettleid-1 > nrrdTypeMax[type]) { |
391 | biffAddf(NRRDnrrdBiffKey, |
392 | "%s: max cc id %u is too large to fit in output type %s", |
393 | me, numsettleid-1, airEnumStr(nrrdType, type)); |
394 | airMopError(mop); return 1; |
395 | } |
396 | } else { |
397 | type = (numsettleid-1 <= nrrdTypeMax[nrrdTypeUChar] |
398 | ? nrrdTypeUChar |
399 | : (numsettleid-1 <= nrrdTypeMax[nrrdTypeUShort] |
400 | ? nrrdTypeUShort |
401 | : nrrdTypeUInt)); |
402 | } |
403 | if (nrrdConvert(nout, nfpid, type)) { |
404 | biffAddf(NRRDnrrdBiffKey, "%s: trouble converting to final output", me); |
405 | airMopError(mop); return 1; |
406 | } |
407 | if (nrrdContentSet_va(nout, func, nin, "%s,%d", |
408 | airEnumStr(nrrdType, type), conny)) { |
409 | biffAddf(NRRDnrrdBiffKey, "%s:", me); |
410 | return 1; |
411 | } |
412 | if (nout != nin) { |
413 | nrrdAxisInfoCopy(nout, nin, NULL((void*)0), NRRD_AXIS_INFO_NONE0); |
414 | } |
415 | /* basic info handled by nrrdConvert */ |
416 | |
417 | airMopOkay(mop); |
418 | return 0; |
419 | } |
420 | |
421 | int |
422 | _nrrdCCAdj_1(unsigned char *out, int numid, const Nrrd *nin) { |
423 | |
424 | AIR_UNUSED(out)(void)(out); |
425 | AIR_UNUSED(numid)(void)(numid); |
426 | AIR_UNUSED(nin)(void)(nin); |
427 | return 0; |
428 | } |
429 | |
430 | int |
431 | _nrrdCCAdj_2(unsigned char *out, unsigned int numid, const Nrrd *nin, |
432 | unsigned int conny) { |
433 | unsigned int (*lup)(const void *, size_t), x, y, sx, sy, id=0; |
434 | double pid[5]={0,0,0,0,0}; |
435 | |
436 | lup = nrrdUILookup[nin->type]; |
437 | sx = AIR_CAST(unsigned int, nin->axis[0].size)((unsigned int)(nin->axis[0].size)); |
438 | sy = AIR_CAST(unsigned int, nin->axis[1].size)((unsigned int)(nin->axis[1].size)); |
439 | for (y=0; y<sy; y++) { |
440 | for (x=0; x<sx; x++) { |
441 | if (!x) { |
442 | pid[1] = GETV_2(-1, y)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y))) && ( ((int)(y))) <= (((int)(sy-1))))) ? lup(nin->data, (-1) + sx*(y)) : 0.5); |
443 | pid[2] = GETV_2(-1, y-1)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1))))) ? lup(nin->data, ( -1) + sx*(y-1)) : 0.5); |
444 | pid[3] = GETV_2(0, y-1)((((0) <= (((int)(0))) && (((int)(0))) <= (((int )(sx-1)))) && ((0) <= (((int)(y-1))) && (( (int)(y-1))) <= (((int)(sy-1))))) ? lup(nin->data, (0) + sx*(y-1)) : 0.5); |
445 | } else { |
446 | pid[1] = id; |
447 | pid[2] = pid[3]; |
448 | pid[3] = pid[4]; |
449 | } |
450 | pid[4] = GETV_2(x+1, y-1)((((0) <= (((int)(x+1))) && (((int)(x+1))) <= ( ((int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1))))) ? lup(nin->data, ( x+1) + sx*(y-1)) : 0.5); |
451 | id = AIR_CAST(unsigned int, GETV_2(x, y))((unsigned int)(((((0) <= (((int)(x))) && (((int)( x))) <= (((int)(sx-1)))) && ((0) <= (((int)(y)) ) && (((int)(y))) <= (((int)(sy-1))))) ? lup(nin-> data, (x) + sx*(y)) : 0.5))); |
452 | #define TADJ(P)if (pid[(P)] != 0.5 && id != pid[(P)]) { out[id + numid *((unsigned int)(pid[(P)]))] = out[((unsigned int)(pid[(P)])) + numid*id] = 1; } \ |
453 | if (pid[(P)] != 0.5 && id != pid[(P)]) { \ |
454 | out[id + numid*AIR_CAST(unsigned int, pid[(P)])((unsigned int)(pid[(P)]))] = \ |
455 | out[AIR_CAST(unsigned int, pid[(P)])((unsigned int)(pid[(P)])) + numid*id] = 1; \ |
456 | } |
457 | TADJ(1)if (pid[(1)] != 0.5 && id != pid[(1)]) { out[id + numid *((unsigned int)(pid[(1)]))] = out[((unsigned int)(pid[(1)])) + numid*id] = 1; }; |
458 | TADJ(3)if (pid[(3)] != 0.5 && id != pid[(3)]) { out[id + numid *((unsigned int)(pid[(3)]))] = out[((unsigned int)(pid[(3)])) + numid*id] = 1; }; |
459 | if (2 == conny) { |
460 | TADJ(2)if (pid[(2)] != 0.5 && id != pid[(2)]) { out[id + numid *((unsigned int)(pid[(2)]))] = out[((unsigned int)(pid[(2)])) + numid*id] = 1; }; |
461 | TADJ(4)if (pid[(4)] != 0.5 && id != pid[(4)]) { out[id + numid *((unsigned int)(pid[(4)]))] = out[((unsigned int)(pid[(4)])) + numid*id] = 1; }; |
462 | } |
463 | } |
464 | } |
465 | |
466 | return 0; |
467 | } |
468 | |
469 | int |
470 | _nrrdCCAdj_3(unsigned char *out, int numid, const Nrrd *nin, |
471 | unsigned int conny) { |
472 | unsigned int (*lup)(const void *, size_t), x, y, z, sx, sy, sz, id=0; |
473 | double pid[14]={0,0,0,0,0,0,0,0,0,0,0,0,0,0}; |
474 | |
475 | lup = nrrdUILookup[nin->type]; |
476 | sx = AIR_CAST(unsigned int, nin->axis[0].size)((unsigned int)(nin->axis[0].size)); |
477 | sy = AIR_CAST(unsigned int, nin->axis[1].size)((unsigned int)(nin->axis[1].size)); |
478 | sz = AIR_CAST(unsigned int, nin->axis[2].size)((unsigned int)(nin->axis[2].size)); |
479 | for (z=0; z<sz; z++) { |
480 | for (y=0; y<sy; y++) { |
481 | for (x=0; x<sx; x++) { |
482 | if (!x) { |
483 | pid[ 1] = GETV_3(-1, y, z)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y))) && ( ((int)(y))) <= (((int)(sy-1)))) && ((0) <= (((int )(z))) && (((int)(z))) <= (((int)(sz-1))))) ? lup( nin->data, (-1) + sx*((y) + sy*(z))) : 0.5); |
484 | pid[ 2] = GETV_3(-1, y-1, z)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z))) && (((int)(z))) <= (((int)(sz-1))))) ? lup(nin->data, (-1) + sx*((y-1) + sy*(z))) : 0.5); |
485 | pid[ 3] = GETV_3( 0, y-1, z)((((0) <= (((int)(0))) && (((int)(0))) <= (((int )(sx-1)))) && ((0) <= (((int)(y-1))) && (( (int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ((( int)(z))) && (((int)(z))) <= (((int)(sz-1))))) ? lup (nin->data, (0) + sx*((y-1) + sy*(z))) : 0.5); |
486 | pid[ 5] = GETV_3(-1, y-1, z-1)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))) )) ? lup(nin->data, (-1) + sx*((y-1) + sy*(z-1))) : 0.5); |
487 | pid[ 8] = GETV_3(-1, y, z-1)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y))) && ( ((int)(y))) <= (((int)(sy-1)))) && ((0) <= (((int )(z-1))) && (((int)(z-1))) <= (((int)(sz-1))))) ? lup (nin->data, (-1) + sx*((y) + sy*(z-1))) : 0.5); |
488 | pid[11] = GETV_3(-1, y+1, z-1)((((0) <= (((int)(-1))) && (((int)(-1))) <= ((( int)(sx-1)))) && ((0) <= (((int)(y+1))) && (((int)(y+1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))) )) ? lup(nin->data, (-1) + sx*((y+1) + sy*(z-1))) : 0.5); |
489 | pid[ 6] = GETV_3( 0, y-1, z-1)((((0) <= (((int)(0))) && (((int)(0))) <= (((int )(sx-1)))) && ((0) <= (((int)(y-1))) && (( (int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ((( int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))))) ? lup(nin->data, (0) + sx*((y-1) + sy*(z-1))) : 0.5); |
490 | pid[ 9] = GETV_3( 0, y, z-1)((((0) <= (((int)(0))) && (((int)(0))) <= (((int )(sx-1)))) && ((0) <= (((int)(y))) && (((int )(y))) <= (((int)(sy-1)))) && ((0) <= (((int)(z -1))) && (((int)(z-1))) <= (((int)(sz-1))))) ? lup (nin->data, (0) + sx*((y) + sy*(z-1))) : 0.5); |
491 | pid[12] = GETV_3( 0, y+1, z-1)((((0) <= (((int)(0))) && (((int)(0))) <= (((int )(sx-1)))) && ((0) <= (((int)(y+1))) && (( (int)(y+1))) <= (((int)(sy-1)))) && ((0) <= ((( int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))))) ? lup(nin->data, (0) + sx*((y+1) + sy*(z-1))) : 0.5); |
492 | } else { |
493 | pid[ 1] = id; |
494 | pid[ 2] = pid[ 3]; |
495 | pid[ 3] = pid[ 4]; |
496 | pid[ 5] = pid[ 6]; |
497 | pid[ 8] = pid[ 9]; |
498 | pid[11] = pid[12]; |
499 | pid[ 6] = pid[ 7]; |
500 | pid[ 9] = pid[10]; |
501 | pid[12] = pid[13]; |
502 | } |
503 | pid[ 4] = GETV_3(x+1, y-1, z)((((0) <= (((int)(x+1))) && (((int)(x+1))) <= ( ((int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z))) && (((int)(z))) <= (((int)(sz-1))))) ? lup(nin->data, (x+1) + sx*((y-1) + sy*(z))) : 0.5); |
504 | pid[ 7] = GETV_3(x+1, y-1, z-1)((((0) <= (((int)(x+1))) && (((int)(x+1))) <= ( ((int)(sx-1)))) && ((0) <= (((int)(y-1))) && (((int)(y-1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))) )) ? lup(nin->data, (x+1) + sx*((y-1) + sy*(z-1))) : 0.5); |
505 | pid[10] = GETV_3(x+1, y, z-1)((((0) <= (((int)(x+1))) && (((int)(x+1))) <= ( ((int)(sx-1)))) && ((0) <= (((int)(y))) && (((int)(y))) <= (((int)(sy-1)))) && ((0) <= (( (int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1)))) ) ? lup(nin->data, (x+1) + sx*((y) + sy*(z-1))) : 0.5); |
506 | pid[13] = GETV_3(x+1, y+1, z-1)((((0) <= (((int)(x+1))) && (((int)(x+1))) <= ( ((int)(sx-1)))) && ((0) <= (((int)(y+1))) && (((int)(y+1))) <= (((int)(sy-1)))) && ((0) <= ( ((int)(z-1))) && (((int)(z-1))) <= (((int)(sz-1))) )) ? lup(nin->data, (x+1) + sx*((y+1) + sy*(z-1))) : 0.5); |
507 | id = AIR_CAST(unsigned int, GETV_3(x, y, z))((unsigned int)(((((0) <= (((int)(x))) && (((int)( x))) <= (((int)(sx-1)))) && ((0) <= (((int)(y)) ) && (((int)(y))) <= (((int)(sy-1)))) && ( (0) <= (((int)(z))) && (((int)(z))) <= (((int)( sz-1))))) ? lup(nin->data, (x) + sx*((y) + sy*(z))) : 0.5) )); |
508 | TADJ(1)if (pid[(1)] != 0.5 && id != pid[(1)]) { out[id + numid *((unsigned int)(pid[(1)]))] = out[((unsigned int)(pid[(1)])) + numid*id] = 1; }; |
509 | TADJ(3)if (pid[(3)] != 0.5 && id != pid[(3)]) { out[id + numid *((unsigned int)(pid[(3)]))] = out[((unsigned int)(pid[(3)])) + numid*id] = 1; }; |
510 | TADJ(9)if (pid[(9)] != 0.5 && id != pid[(9)]) { out[id + numid *((unsigned int)(pid[(9)]))] = out[((unsigned int)(pid[(9)])) + numid*id] = 1; }; |
511 | if (2 <= conny) { |
512 | TADJ(2)if (pid[(2)] != 0.5 && id != pid[(2)]) { out[id + numid *((unsigned int)(pid[(2)]))] = out[((unsigned int)(pid[(2)])) + numid*id] = 1; }; TADJ(4)if (pid[(4)] != 0.5 && id != pid[(4)]) { out[id + numid *((unsigned int)(pid[(4)]))] = out[((unsigned int)(pid[(4)])) + numid*id] = 1; }; |
513 | TADJ(6)if (pid[(6)] != 0.5 && id != pid[(6)]) { out[id + numid *((unsigned int)(pid[(6)]))] = out[((unsigned int)(pid[(6)])) + numid*id] = 1; }; TADJ(8)if (pid[(8)] != 0.5 && id != pid[(8)]) { out[id + numid *((unsigned int)(pid[(8)]))] = out[((unsigned int)(pid[(8)])) + numid*id] = 1; }; TADJ(10)if (pid[(10)] != 0.5 && id != pid[(10)]) { out[id + numid *((unsigned int)(pid[(10)]))] = out[((unsigned int)(pid[(10)] )) + numid*id] = 1; }; TADJ(12)if (pid[(12)] != 0.5 && id != pid[(12)]) { out[id + numid *((unsigned int)(pid[(12)]))] = out[((unsigned int)(pid[(12)] )) + numid*id] = 1; }; |
514 | if (3 == conny) { |
515 | TADJ(5)if (pid[(5)] != 0.5 && id != pid[(5)]) { out[id + numid *((unsigned int)(pid[(5)]))] = out[((unsigned int)(pid[(5)])) + numid*id] = 1; }; TADJ(7)if (pid[(7)] != 0.5 && id != pid[(7)]) { out[id + numid *((unsigned int)(pid[(7)]))] = out[((unsigned int)(pid[(7)])) + numid*id] = 1; }; TADJ(11)if (pid[(11)] != 0.5 && id != pid[(11)]) { out[id + numid *((unsigned int)(pid[(11)]))] = out[((unsigned int)(pid[(11)] )) + numid*id] = 1; }; TADJ(13)if (pid[(13)] != 0.5 && id != pid[(13)]) { out[id + numid *((unsigned int)(pid[(13)]))] = out[((unsigned int)(pid[(13)] )) + numid*id] = 1; }; |
516 | } |
517 | } |
518 | } |
519 | } |
520 | } |
521 | |
522 | return 0; |
523 | } |
524 | |
525 | int |
526 | _nrrdCCAdj_N(unsigned char *out, int numid, const Nrrd *nin, |
527 | unsigned int conny) { |
528 | static const char me[]="_nrrdCCAdj_N"; |
529 | |
530 | AIR_UNUSED(out)(void)(out); |
531 | AIR_UNUSED(numid)(void)(numid); |
532 | AIR_UNUSED(nin)(void)(nin); |
533 | AIR_UNUSED(conny)(void)(conny); |
534 | biffAddf(NRRDnrrdBiffKey, "%s: sorry, not implemented", me); |
535 | return 1; |
536 | } |
537 | |
538 | int |
539 | nrrdCCAdjacency(Nrrd *nout, const Nrrd *nin, unsigned int conny) { |
540 | static const char me[]="nrrdCCAdjacency", func[]="ccadj"; |
541 | int ret; |
542 | unsigned int maxid; |
543 | unsigned char *out; |
544 | |
545 | if (!( nout && nrrdCCValid(nin) )) { |
546 | biffAddf(NRRDnrrdBiffKey, "%s: invalid args", me); |
547 | return 1; |
548 | } |
549 | if (nout == nin) { |
550 | biffAddf(NRRDnrrdBiffKey, "%s: nout == nin disallowed", me); |
551 | return 1; |
552 | } |
553 | if (!( AIR_IN_CL(1, conny, nin->dim)((1) <= (conny) && (conny) <= (nin->dim)) )) { |
554 | biffAddf(NRRDnrrdBiffKey, "%s: connectivity value must be in [1..%d] for %d-D " |
555 | "data (not %d)", me, nin->dim, nin->dim, conny); |
556 | return 1; |
557 | } |
558 | maxid = nrrdCCMax(nin); |
559 | if (nrrdMaybeAlloc_va(nout, nrrdTypeUChar, 2, |
560 | AIR_CAST(size_t, maxid+1)((size_t)(maxid+1)), |
561 | AIR_CAST(size_t, maxid+1)((size_t)(maxid+1)))) { |
562 | biffAddf(NRRDnrrdBiffKey, "%s: trouble allocating output", me); |
563 | return 1; |
564 | } |
565 | out = (unsigned char *)(nout->data); |
566 | |
567 | switch(nin->dim) { |
568 | case 1: |
569 | ret = _nrrdCCAdj_1(out, maxid+1, nin); |
570 | break; |
571 | case 2: |
572 | ret = _nrrdCCAdj_2(out, maxid+1, nin, conny); |
573 | break; |
574 | case 3: |
575 | ret = _nrrdCCAdj_3(out, maxid+1, nin, conny); |
576 | break; |
577 | default: |
578 | ret = _nrrdCCAdj_N(out, maxid+1, nin, conny); |
579 | break; |
580 | } |
581 | if (ret) { |
582 | biffAddf(NRRDnrrdBiffKey, "%s: trouble", me); |
583 | return 1; |
584 | } |
585 | /* this goofiness is just so that histo-based projections |
586 | return the sorts of values that we expect */ |
587 | nout->axis[0].center = nout->axis[1].center = nrrdCenterCell; |
588 | nout->axis[0].min = nout->axis[1].min = -0.5; |
589 | nout->axis[0].max = nout->axis[1].max = maxid + 0.5; |
590 | if (nrrdContentSet_va(nout, func, nin, "%d", conny)) { |
591 | biffAddf(NRRDnrrdBiffKey, "%s:", me); |
592 | return 1; |
593 | } |
594 | |
595 | return 0; |
596 | } |
597 | |
598 | /* |
599 | ******** nrrdCCMerge |
600 | ** |
601 | ** Slightly-too-multi-purpose tool for merging small connected components |
602 | ** (CCs) into larger ones, according to a number of possible different |
603 | ** constraints, as explained below. |
604 | ** |
605 | ** valDir: (value direction) uses information about the original values |
606 | ** in the CC to constrain whether darker gets merged into brighter, or vice |
607 | ** versa, or neither. For non-zero valDir values, a non-NULL _nval (from |
608 | ** nrrdCCFind) must be passed. |
609 | ** valDir > 0 : merge dark CCs into bright, but not vice versa |
610 | ** valDir = 0 : merge either way, values are irrelevant |
611 | ** valDir < 0 : merge bright CCs into dark, but not vice versa |
612 | ** When merging with multiple neighbors (maxNeighbor > 1), the value |
613 | ** of the largest neighbor is considered. |
614 | ** |
615 | ** maxSize: a cap on how large "small" is- CCs any larger than maxSize are |
616 | ** not merged, as they are deemed too significant. Or, a maxSize of 0 says |
617 | ** size is no object for merging CCs. |
618 | ** |
619 | ** maxNeighbor: a maximum number of neighbors that a CC can have (either |
620 | ** bigger than the CC or not) if it is to be merged. Use 1 to merge |
621 | ** isolated islands into their surrounds, 2 to merge CC with the larger |
622 | ** of their two neighbors, etc., or 0 to allow any number of neighbors. |
623 | ** |
624 | ** conny: passed to nrrdCCAdjacency() when determining neighbors |
625 | ** |
626 | ** In order to prevent weirdness, the merging done in one call to this |
627 | ** function is not transitive: if A is merged to B, then B will not be |
628 | ** merged to anything else, even if meets all the requirements defined |
629 | ** by the given parameters. This is accomplished by working from the |
630 | ** smallest CCs to the largest. Iterated calls may be needed to acheive |
631 | ** the desired effect. |
632 | ** |
633 | ** Note: the output of this is not "settled"- the CC id values are not |
634 | ** shiftward downwards to their lowest possible values, since this would |
635 | ** needlessly invalidate the nval value store. |
636 | */ |
637 | int |
638 | nrrdCCMerge(Nrrd *nout, const Nrrd *nin, Nrrd *_nval, |
639 | int valDir, unsigned int maxSize, unsigned int maxNeighbor, |
640 | unsigned int conny) { |
641 | static const char me[]="nrrdCCMerge", func[]="ccmerge"; |
642 | const char *valcnt; |
643 | unsigned int _i, i, j, bigi=0, numid, *size, *sizeId, |
644 | *nn, /* number of neighbors */ |
645 | *val=NULL((void*)0), *hit, |
646 | (*lup)(const void *, size_t), (*ins)(void *, size_t, unsigned int); |
647 | Nrrd *nadj, *nsize, *nval=NULL((void*)0), *nnn; |
648 | unsigned char *adj; |
649 | unsigned int *map, *id; |
650 | airArray *mop; |
651 | size_t I, NN; |
652 | |
653 | mop = airMopNew(); |
654 | if (!( nout && nrrdCCValid(nin) )) { |
655 | /* _nval can be NULL */ |
656 | biffAddf(NRRDnrrdBiffKey, "%s: invalid args", me); |
657 | airMopError(mop); return 1; |
658 | } |
659 | if (valDir) { |
660 | airMopAdd(mop, nval = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); |
661 | if (nrrdConvert(nval, _nval, nrrdTypeUInt)) { |
662 | biffAddf(NRRDnrrdBiffKey, "%s: value-directed merging needs usable nval", me); |
663 | airMopError(mop); return 1; |
664 | } |
665 | val = (unsigned int*)(nval->data); |
666 | } |
667 | if (nout != nin) { |
668 | if (nrrdCopy(nout, nin)) { |
669 | biffAddf(NRRDnrrdBiffKey, "%s:", me); |
670 | airMopError(mop); return 1; |
671 | } |
672 | } |
673 | airMopAdd(mop, nadj = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); |
674 | airMopAdd(mop, nsize = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); |
675 | airMopAdd(mop, nnn = nrrdNew(), (airMopper)nrrdNuke, airMopAlways); |
676 | |
677 | if (nrrdCCSize(nsize, nin) |
678 | || nrrdCopy(nnn, nsize) /* just to allocate to right size and type */ |
679 | || nrrdCCAdjacency(nadj, nin, conny)) { |
680 | biffAddf(NRRDnrrdBiffKey, "%s:", me); |
681 | airMopError(mop); return 1; |
682 | } |
683 | size = (unsigned int*)(nsize->data); |
684 | adj = (unsigned char*)(nadj->data); |
685 | nn = (unsigned int*)(nnn->data); |
686 | numid = AIR_CAST(unsigned int, nsize->axis[0].size)((unsigned int)(nsize->axis[0].size)); |
687 | for (i=0; i<numid; i++) { |
688 | nn[i] = 0; |
689 | for (j=0; j<numid; j++) { |
690 | nn[i] += adj[j + numid*i]; |
691 | } |
692 | } |
693 | map = AIR_MALLOC(numid, unsigned int)(unsigned int*)(malloc((numid)*sizeof(unsigned int))); |
694 | id = AIR_MALLOC(numid, unsigned int)(unsigned int*)(malloc((numid)*sizeof(unsigned int))); |
695 | hit = AIR_MALLOC(numid, unsigned int)(unsigned int*)(malloc((numid)*sizeof(unsigned int))); |
696 | sizeId = AIR_MALLOC(2*numid, unsigned int)(unsigned int*)(malloc((2*numid)*sizeof(unsigned int))); |
697 | /* we add to the mops BEFORE error checking so that anything non-NULL |
698 | will get airFree'd, and happily airFree is a no-op on NULL */ |
699 | airMopAdd(mop, map, airFree, airMopAlways); |
700 | airMopAdd(mop, id, airFree, airMopAlways); |
701 | airMopAdd(mop, hit, airFree, airMopAlways); |
702 | airMopAdd(mop, sizeId, airFree, airMopAlways); |
703 | if (!(map && id && hit && sizeId)) { |
704 | biffAddf(NRRDnrrdBiffKey, "%s: couldn't allocate buffers", me); |
705 | airMopError(mop); return 1; |
706 | } |
707 | |
708 | /* store and sort size/id pairs */ |
709 | for (i=0; i<numid; i++) { |
710 | sizeId[0 + 2*i] = size[i]; |
711 | sizeId[1 + 2*i] = i; |
712 | } |
713 | qsort(sizeId, numid, 2*sizeof(unsigned int), nrrdValCompare[nrrdTypeUInt]); |
714 | for (i=0; i<numid; i++) { |
715 | id[i] = sizeId[1 + 2*i]; |
716 | } |
717 | |
718 | /* initialize arrays */ |
719 | for (i=0; i<numid; i++) { |
720 | map[i] = i; |
721 | hit[i] = AIR_FALSE0; |
722 | } |
723 | /* _i goes through 0 to numid-1, |
724 | i goes through the CC ids in ascending order of size */ |
725 | for (_i=0; _i<numid; _i++) { |
726 | i = id[_i]; |
727 | if (hit[i]) { |
728 | continue; |
729 | } |
730 | if (maxSize && (size[i] > maxSize)) { |
731 | continue; |
732 | } |
733 | if (maxNeighbor && (nn[i] > maxNeighbor)) { |
734 | continue; |
735 | } |
736 | /* find biggest neighbor, exploiting the fact that we already |
737 | sorted CC ids on size. j descends through indices of id[], |
738 | bigi goes through CC ids which are larger than CC i */ |
739 | for (j=numid-1; j>_i; j--) { |
740 | bigi = id[j]; |
741 | if (adj[bigi + numid*i]) |
742 | break; |
743 | } |
744 | if (j == _i) { |
745 | continue; /* we had no neighbors ?!?! */ |
746 | } |
747 | if (valDir && (AIR_CAST(int, val[bigi])((int)(val[bigi])) |
748 | - AIR_CAST(int, val[i])((int)(val[i])))*valDir < 0 ) { |
749 | continue; |
750 | } |
751 | /* else all criteria for merging have been met */ |
752 | map[i] = bigi; |
753 | hit[bigi] = AIR_TRUE1; |
754 | } |
755 | lup = nrrdUILookup[nin->type]; |
756 | ins = nrrdUIInsert[nout->type]; |
757 | NN = nrrdElementNumber(nin); |
758 | for (I=0; I<NN; I++) { |
759 | ins(nout->data, I, map[lup(nin->data, I)]); |
760 | } |
761 | |
762 | valcnt = ((_nval && _nval->content) |
763 | ? _nval->content |
764 | : nrrdStateUnknownContent); |
765 | if ( (valDir && nrrdContentSet_va(nout, func, nin, "%c(%s),%d,%d,%d", |
766 | (valDir > 0 ? '+' : '-'), valcnt, |
767 | maxSize, maxNeighbor, conny)) |
768 | || |
769 | (!valDir && nrrdContentSet_va(nout, func, nin, ".,%d,%d,%d", |
770 | maxSize, maxNeighbor, conny)) ) { |
771 | biffAddf(NRRDnrrdBiffKey, "%s:", me); |
772 | airMopError(mop); return 1; |
773 | } |
774 | /* basic info handled by nrrdCopy */ |
775 | airMopOkay(mop); |
776 | return 0; |
777 | } |
778 | |
779 | /* |
780 | ******** nrrdCCRevalue() |
781 | ** |
782 | ** assigns the original values back to the connected components |
783 | ** obviously, this could be subsumed by nrrdApply1DLut(), but this |
784 | ** is so special purpose that it seemed simpler to code from scratch |
785 | */ |
786 | int |
787 | nrrdCCRevalue (Nrrd *nout, const Nrrd *nin, const Nrrd *nval) { |
788 | static const char me[]="nrrdCCRevalue"; |
789 | size_t I, NN; |
790 | unsigned int (*vlup)(const void *, size_t), (*ilup)(const void *, size_t), |
791 | (*ins)(void *, size_t, unsigned int); |
792 | |
793 | if (!( nout && nrrdCCValid(nin) && nval )) { |
794 | biffAddf(NRRDnrrdBiffKey, "%s: invalid args", me); |
795 | return 1; |
796 | } |
797 | if (nrrdConvert(nout, nin, nval->type)) { |
798 | biffAddf(NRRDnrrdBiffKey, "%s: couldn't initialize output", me); |
799 | return 1; |
800 | } |
801 | NN = nrrdElementNumber(nin); |
802 | vlup = nrrdUILookup[nval->type]; |
803 | ilup = nrrdUILookup[nin->type]; |
804 | ins = nrrdUIInsert[nout->type]; |
805 | for (I=0; I<NN; I++) { |
806 | ins(nout->data, I, vlup(nval->data, ilup(nin->data, I))); |
807 | } |
808 | /* basic info handled by nrrdConvert */ |
809 | |
810 | return 0; |
811 | } |
812 | |
813 | int |
814 | nrrdCCSettle(Nrrd *nout, Nrrd **nvalP, const Nrrd *nin) { |
815 | static const char me[]="nrrdCCSettle", func[]="ccsettle"; |
816 | unsigned int numid, maxid, jd, id, *map, |
817 | (*lup)(const void *, size_t), (*ins)(void *, size_t, unsigned int); |
818 | size_t I, NN; |
819 | airArray *mop; |
820 | |
821 | mop = airMopNew(); |
822 | if (!( nout && nrrdCCValid(nin) )) { |
823 | /* nvalP can be NULL */ |
824 | biffAddf(NRRDnrrdBiffKey, "%s: invalid args", me); |
825 | airMopError(mop); return 1; |
826 | } |
827 | if (nrrdCopy(nout, nin)) { |
828 | biffAddf(NRRDnrrdBiffKey, "%s: initial copy failed", me); |
829 | airMopError(mop); return 1; |
830 | } |
831 | maxid = nrrdCCMax(nin); |
832 | lup = nrrdUILookup[nin->type]; |
833 | ins = nrrdUIInsert[nin->type]; |
834 | NN = nrrdElementNumber(nin); |
835 | map = AIR_CALLOC(maxid+1, unsigned int)(unsigned int*)(calloc((maxid+1), sizeof(unsigned int))); /* we do need it zeroed out */ |
836 | if (!map) { |
837 | biffAddf(NRRDnrrdBiffKey, "%s: couldn't allocate internal LUT", me); |
838 | airMopError(mop); return 1; |
839 | } |
840 | airMopAdd(mop, map, airFree, airMopAlways); |
841 | for (I=0; I<NN; I++) { |
842 | map[lup(nin->data, I)] = 1; |
843 | } |
844 | numid = 0; |
845 | for (jd=0; jd<=maxid; jd++) { |
846 | numid += map[jd]; |
847 | } |
848 | |
849 | if (nvalP) { |
850 | if (!(*nvalP)) { |
851 | *nvalP = nrrdNew(); |
852 | } |
853 | if (nrrdMaybeAlloc_va(*nvalP, nin->type, 1, |
854 | AIR_CAST(size_t, numid)((size_t)(numid)))) { |
855 | biffAddf(NRRDnrrdBiffKey, "%s: couldn't allocate output value list", me); |
856 | airMopError(mop); return 1; |
857 | } |
858 | airMopAdd(mop, nvalP, (airMopper)airSetNull, airMopOnError); |
859 | airMopAdd(mop, *nvalP, (airMopper)nrrdNuke, airMopOnError); |
860 | } |
861 | |
862 | id = 0; |
863 | for (jd=0; jd<=maxid; jd++) { |
864 | if (map[jd]) { |
865 | map[jd] = id; |
866 | if (nvalP) { |
867 | ins((*nvalP)->data, id, jd); |
868 | } |
869 | id++; |
870 | } |
871 | } |
872 | for (I=0; I<NN; I++) { |
873 | ins(nout->data, I, map[lup(nin->data, I)]); |
874 | } |
875 | |
876 | if (nrrdContentSet_va(nout, func, nin, "")) { |
877 | biffAddf(NRRDnrrdBiffKey, "%s:", me); |
878 | airMopError(mop); return 1; |
879 | } |
880 | /* basic info handled by nrrdCopy */ |
881 | airMopOkay(mop); |
882 | return 0; |
883 | } |