GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
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 |
** making these typedefs here allows us to use one token for both |
||
29 |
** constructing function names, and for specifying argument types |
||
30 |
*/ |
||
31 |
typedef signed char CH; |
||
32 |
typedef unsigned char UC; |
||
33 |
typedef signed short SH; |
||
34 |
typedef unsigned short US; |
||
35 |
/* Microsoft apparently uses 'IN' as a keyword, so we changed 'IN' to 'JN'. */ |
||
36 |
typedef signed int JN; |
||
37 |
typedef unsigned int UI; |
||
38 |
typedef airLLong LL; |
||
39 |
/* ui64 to double conversion is not implemented, sorry */ |
||
40 |
#if _MSC_VER < 1300 |
||
41 |
typedef airLLong UL; |
||
42 |
#else |
||
43 |
typedef airULLong UL; |
||
44 |
#endif |
||
45 |
typedef float FL; |
||
46 |
typedef double DB; |
||
47 |
typedef size_t IT; |
||
48 |
/* typedef long double LD; */ |
||
49 |
|||
50 |
/* |
||
51 |
** I don't think that I can get out of defining this macro twice, |
||
52 |
** because of the rules of C preprocessor macro expansion. If |
||
53 |
** you can figure out a way to not use two identical macros, then |
||
54 |
** email me (glk@uchicago.edu) and I'll send you money for dinner. |
||
55 |
** |
||
56 |
** >>> MAP1 and MAP2 need to be identical <<< |
||
57 |
*/ |
||
58 |
|||
59 |
#define MAP1(F, A) \ |
||
60 |
F(A, CH) \ |
||
61 |
F(A, UC) \ |
||
62 |
F(A, SH) \ |
||
63 |
F(A, US) \ |
||
64 |
F(A, JN) \ |
||
65 |
F(A, UI) \ |
||
66 |
F(A, LL) \ |
||
67 |
F(A, UL) \ |
||
68 |
F(A, FL) \ |
||
69 |
F(A, DB) |
||
70 |
/* F(A, LD) */ |
||
71 |
|||
72 |
#define MAP2(F, A) \ |
||
73 |
F(A, CH) \ |
||
74 |
F(A, UC) \ |
||
75 |
F(A, SH) \ |
||
76 |
F(A, US) \ |
||
77 |
F(A, JN) \ |
||
78 |
F(A, UI) \ |
||
79 |
F(A, LL) \ |
||
80 |
F(A, UL) \ |
||
81 |
F(A, FL) \ |
||
82 |
F(A, DB) |
||
83 |
/* F(A, LD) */ |
||
84 |
|||
85 |
/* |
||
86 |
** _nrrdConv<Ta><Tb>() |
||
87 |
** |
||
88 |
** given two arrays, a and b, of different types (Ta and Tb) but equal |
||
89 |
** size N, _nrrdConvTaTb(a, b, N) will copy all the values from b into |
||
90 |
** a, thereby effecting the same type-conversion as one gets with a |
||
91 |
** cast. See K+R Appendix A6 (pg. 197) for the details of what that |
||
92 |
** entails. There are plenty of situations where the results are |
||
93 |
** "undefined" (assigning -23 to an unsigned char); the point here is |
||
94 |
** simply to make available on arrays all the same behavior you can |
||
95 |
** get from scalars. |
||
96 |
*/ |
||
97 |
#define CONV_DEF(TA, TB) \ |
||
98 |
static void \ |
||
99 |
_nrrdConv##TA##TB(TA *a, const TB *b, IT N) { \ |
||
100 |
size_t ii; \ |
||
101 |
for (ii=0; ii<N; ii++) { \ |
||
102 |
a[ii] = AIR_CAST(TA, b[ii]); \ |
||
103 |
} \ |
||
104 |
} |
||
105 |
|||
106 |
/* |
||
107 |
** _nrrdClCv<Ta><Tb>() |
||
108 |
** |
||
109 |
** same as _nrrdConv<Ta><Tb>(), but with clamping to the representable |
||
110 |
** range of values of the output type, using a double as intermediate |
||
111 |
** storage type HEY WHICH MEANS THAT LONG LONG (BOTH SIGNED AND UNSIGNED) |
||
112 |
** may suffer loss of data!!! |
||
113 |
*/ |
||
114 |
#define CLCV_DEF(TA, TB) \ |
||
115 |
static void \ |
||
116 |
_nrrdClCv##TA##TB(TA *a, const TB *b, IT N) { \ |
||
117 |
size_t ii; \ |
||
118 |
for (ii=0; ii<N; ii++) { \ |
||
119 |
a[ii] = AIR_CAST(TA, _nrrdDClamp##TA(AIR_CAST(double, b[ii]))); \ |
||
120 |
} \ |
||
121 |
} |
||
122 |
|||
123 |
/* |
||
124 |
** _nrrdCcrd<Ta><Tb>() |
||
125 |
** |
||
126 |
** like _nrrdClCv<Ta><Tb>() and _nrrdConv<Ta><Tb>(), but with the |
||
127 |
** ability to control if there is rounding and/or clamping. As above, |
||
128 |
** there may be loss of precision with long long input. |
||
129 |
*/ |
||
130 |
#define CCRD_DEF(TA, TB) \ |
||
131 |
static void \ |
||
132 |
_nrrdCcrd##TA##TB(TA *a, const TB *b, IT N, \ |
||
133 |
int doClamp, int roundd) { \ |
||
134 |
size_t ii; \ |
||
135 |
for (ii=0; ii<N; ii++) { \ |
||
136 |
double ccrdTmp = AIR_CAST(double, b[ii]); \ |
||
137 |
ccrdTmp = (roundd > 0 \ |
||
138 |
? floor(ccrdTmp + 0.5) \ |
||
139 |
: (roundd < 0 \ |
||
140 |
? ceil(ccrdTmp - 0.5) \ |
||
141 |
: ccrdTmp)); \ |
||
142 |
ccrdTmp = (doClamp ? _nrrdDClamp##TA(ccrdTmp) : ccrdTmp); \ |
||
143 |
a[ii] = AIR_CAST(TA, ccrdTmp); \ |
||
144 |
} \ |
||
145 |
} |
||
146 |
|||
147 |
/* |
||
148 |
** These makes the definition of later arrays shorter |
||
149 |
*/ |
||
150 |
typedef void (*CF)(void *, const void *, IT); |
||
151 |
typedef void (*CN)(void *, const void *, IT, int, int); |
||
152 |
|||
153 |
/* |
||
154 |
** the individual converter's appearance in the array initialization, |
||
155 |
** using the cast to the typedefs above |
||
156 |
*/ |
||
157 |
#define CONV_LIST(TA, TB) (CF)_nrrdConv##TA##TB, |
||
158 |
#define CLCV_LIST(TA, TB) (CF)_nrrdClCv##TA##TB, |
||
159 |
#define CCRD_LIST(TA, TB) (CN)_nrrdCcrd##TA##TB, |
||
160 |
|||
161 |
/* |
||
162 |
** the brace-delimited list of all converters _to_ type TA |
||
163 |
*/ |
||
164 |
#define CONVTO_LIST(_dummy_, TA) {NULL, MAP2(CONV_LIST, TA) NULL}, |
||
165 |
#define CLCVTO_LIST(_dummy_, TA) {NULL, MAP2(CLCV_LIST, TA) NULL}, |
||
166 |
#define CCRDTO_LIST(_dummy_, TA) {NULL, MAP2(CCRD_LIST, TA) NULL}, |
||
167 |
|||
168 |
|||
169 |
|||
170 |
/* |
||
171 |
** This is where the actual emitted code starts ... |
||
172 |
*/ |
||
173 |
|||
174 |
|||
175 |
/* |
||
176 |
** the clamping functions were moved here from accessors.c in order |
||
177 |
** to create the combined clamp-and-convert functions |
||
178 |
*/ |
||
179 |
|||
180 |
/* |
||
181 |
******** nrrdFClamp |
||
182 |
** |
||
183 |
** for integral types, clamps a given float to the range representable |
||
184 |
** by that type; for floating point types we just return |
||
185 |
** the given number, since every float must fit in a double. |
||
186 |
*/ |
||
187 |
static float _nrrdFClampCH(FL v) { return AIR_CLAMP(SCHAR_MIN, v, SCHAR_MAX);} |
||
188 |
static float _nrrdFClampUC(FL v) { return AIR_CLAMP(0, v, UCHAR_MAX);} |
||
189 |
static float _nrrdFClampSH(FL v) { return AIR_CLAMP(SHRT_MIN, v, SHRT_MAX);} |
||
190 |
static float _nrrdFClampUS(FL v) { return AIR_CLAMP(0, v, USHRT_MAX);} |
||
191 |
static float _nrrdFClampJN(FL v) { return AIR_CLAMP(INT_MIN, v, INT_MAX);} |
||
192 |
static float _nrrdFClampUI(FL v) { return AIR_CLAMP(0, v, UINT_MAX);} |
||
193 |
static float _nrrdFClampLL(FL v) { return AIR_CLAMP(NRRD_LLONG_MIN, v, |
||
194 |
NRRD_LLONG_MAX);} |
||
195 |
static float _nrrdFClampUL(FL v) { return AIR_CLAMP(0, v, NRRD_ULLONG_MAX);} |
||
196 |
static float _nrrdFClampFL(FL v) { return v; } |
||
197 |
static float _nrrdFClampDB(FL v) { return v; } |
||
198 |
float (* |
||
199 |
nrrdFClamp[NRRD_TYPE_MAX+1])(FL) = { |
||
200 |
NULL, |
||
201 |
_nrrdFClampCH, |
||
202 |
_nrrdFClampUC, |
||
203 |
_nrrdFClampSH, |
||
204 |
_nrrdFClampUS, |
||
205 |
_nrrdFClampJN, |
||
206 |
_nrrdFClampUI, |
||
207 |
_nrrdFClampLL, |
||
208 |
_nrrdFClampUL, |
||
209 |
_nrrdFClampFL, |
||
210 |
_nrrdFClampDB, |
||
211 |
NULL}; |
||
212 |
|||
213 |
/* |
||
214 |
******** nrrdDClamp |
||
215 |
** |
||
216 |
** same as nrrdDClamp, but for doubles. One change: in the case of |
||
217 |
** floats, doubles are clamped to the range -FLT_MAX to FLT_MAX. |
||
218 |
*/ |
||
219 |
static double _nrrdDClampCH(DB v) { return AIR_CLAMP(SCHAR_MIN, v, SCHAR_MAX);} |
||
220 |
static double _nrrdDClampUC(DB v) { return AIR_CLAMP(0, v, UCHAR_MAX);} |
||
221 |
static double _nrrdDClampSH(DB v) { return AIR_CLAMP(SHRT_MIN, v, SHRT_MAX);} |
||
222 |
static double _nrrdDClampUS(DB v) { return AIR_CLAMP(0, v, USHRT_MAX);} |
||
223 |
✓✗ | 160000 |
static double _nrrdDClampJN(DB v) { return AIR_CLAMP(INT_MIN, v, INT_MAX);} |
224 |
static double _nrrdDClampUI(DB v) { return AIR_CLAMP(0, v, UINT_MAX);} |
||
225 |
static double _nrrdDClampLL(DB v) { return AIR_CLAMP(NRRD_LLONG_MIN, v, |
||
226 |
NRRD_LLONG_MAX);} |
||
227 |
static double _nrrdDClampUL(DB v) { return AIR_CLAMP(0, v, NRRD_ULLONG_MAX);} |
||
228 |
static double _nrrdDClampFL(DB v) { return AIR_CLAMP(-FLT_MAX, v, FLT_MAX); } |
||
229 |
static double _nrrdDClampDB(DB v) { return v; } |
||
230 |
double (* |
||
231 |
nrrdDClamp[NRRD_TYPE_MAX+1])(DB) = { |
||
232 |
NULL, |
||
233 |
_nrrdDClampCH, |
||
234 |
_nrrdDClampUC, |
||
235 |
_nrrdDClampSH, |
||
236 |
_nrrdDClampUS, |
||
237 |
_nrrdDClampJN, |
||
238 |
_nrrdDClampUI, |
||
239 |
_nrrdDClampLL, |
||
240 |
_nrrdDClampUL, |
||
241 |
_nrrdDClampFL, |
||
242 |
_nrrdDClampDB, |
||
243 |
NULL}; |
||
244 |
|||
245 |
|||
246 |
/* |
||
247 |
** Define all the converters. |
||
248 |
*/ |
||
249 |
✗✗✓✓ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✓✓ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✓✓ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✓✓ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✓✓ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✓✓ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✓✓ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✓✓ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✗✗✓✓ ✗✗✗✗ ✗✗✗✗ ✗✗✗✗ ✓✓✗✗ |
13202380 |
MAP1(MAP2, CONV_DEF) |
250 |
MAP1(MAP2, CLCV_DEF) |
||
251 |
MAP1(MAP2, CCRD_DEF) |
||
252 |
|||
253 |
|||
254 |
/* |
||
255 |
** Initialize the converter arrays. |
||
256 |
** |
||
257 |
** Each definition generates one incredibly long line of text, which |
||
258 |
** hopefully will not break a poor compiler with limitations on |
||
259 |
** line-length... |
||
260 |
*/ |
||
261 |
CF |
||
262 |
_nrrdConv[NRRD_TYPE_MAX+1][NRRD_TYPE_MAX+1] = { |
||
263 |
{NULL}, |
||
264 |
MAP1(CONVTO_LIST, _dummy_) |
||
265 |
{NULL} |
||
266 |
}; |
||
267 |
|||
268 |
CF |
||
269 |
_nrrdClampConv[NRRD_TYPE_MAX+1][NRRD_TYPE_MAX+1] = { |
||
270 |
{NULL}, |
||
271 |
MAP1(CLCVTO_LIST, _dummy_) |
||
272 |
{NULL} |
||
273 |
}; |
||
274 |
|||
275 |
CN |
||
276 |
_nrrdCastClampRound[NRRD_TYPE_MAX+1][NRRD_TYPE_MAX+1] = { |
||
277 |
{NULL}, |
||
278 |
MAP1(CCRDTO_LIST, _dummy_) |
||
279 |
{NULL} |
||
280 |
}; |
Generated by: GCOVR (Version 3.3) |