Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] Annotation of /branches/vis12/src/lib/common/dyn-seq.c
ViewVC logotype

Annotation of /branches/vis12/src/lib/common/dyn-seq.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2033 - (view) (download) (as text)

1 : jhr 1733 /*! \file dyn-seq.c
2 :     *
3 :     * \author John Reppy
4 :     *
5 :     * An implementation of dynamic sequences.
6 :     */
7 :    
8 :     /*
9 :     * COPYRIGHT (c) 2012 The Diderot Project (http://diderot-language.cs.uchicago.edu)
10 :     * All rights reserved.
11 :     */
12 :    
13 :     #include "Diderot/diderot.h"
14 : jhr 1978 #include <teem/nrrd.h>
15 : jhr 1733
16 :     // compute the address of the i'th element in the sequence
17 :     STATIC_INLINE void* ElemAddr(void *base, size_t elemSz, unsigned int i)
18 :     {
19 :     return (void *)((char *)base + i*elemSz);
20 :     }
21 :    
22 :     //! append an element to a sequence
23 :     Diderot_DynSeq_t *Diderot_DynSeqAppend (size_t elemSz, Diderot_DynSeq_t *seq, void *item)
24 :     {
25 :     if (seq->nElems == seq->size) {
26 :     // grow the data array
27 :     unsigned int newSize = (seq->size < 64) ? seq->size + 8 : seq->size + 64;
28 :     void *newData = CheckedAlloc (elemSz * newSize);
29 :     Diderot_DynSeqCopy (elemSz, newData, seq);
30 :     seq->size = newSize;
31 :     seq->base = 0;
32 :     FREE(seq->data);
33 :     seq->data = newData;
34 :     }
35 :     unsigned int i = (seq->base + seq->nElems) % seq->size;
36 : jhr 1906 seq->nElems++;
37 : jhr 1733 memcpy(ElemAddr(seq->data, elemSz, i), item, elemSz);
38 :     return seq;
39 :     }
40 :    
41 :     //! prepend an element to a sequence
42 :     //Diderot_DynSeq_t *Diderot_DynSeqPrepend (size_t elemSz, void *, Diderot_DynSeq_t *);
43 :    
44 :     //! concatenate two sequences
45 :     //Diderot_DynSeq_t *Diderot_DynSeqConcat (size_t elemSz, Diderot_DynSeq_t *, Diderot_DynSeq_t *);
46 :    
47 :     //! \brief copy the elements of a sequence to an array
48 :     //! \param elemSz the size of the sequence elements in bytes
49 :     //! \param dst the destination array
50 :     //! \param seq the source sequence
51 :     //! \return the address of the element that follows the array
52 :     void *Diderot_DynSeqCopy (size_t elemSz, void *dst, Diderot_DynSeq_t *seq)
53 :     {
54 :     unsigned int n = seq->nElems;
55 :     if (seq->base + n > seq->size) {
56 :     // sequence wraps around, so we need to copy it in two steps
57 :     n = seq->size - seq->base;
58 :     memcpy (dst, ElemAddr(seq->data, elemSz, seq->base), n*elemSz);
59 :     dst = (void *)((char *)dst + n*elemSz);
60 :     n = seq->nElems - n;
61 :     memcpy (dst, ElemAddr(seq->data, elemSz, 0), n*elemSz);
62 :     return (void *)((char *)dst + n*elemSz);
63 :     }
64 :     else {
65 :     size_t cpySz = n*elemSz;
66 :     memcpy (dst, ElemAddr(seq->data, elemSz, seq->base), cpySz);
67 :     return (void *)((char *)dst + cpySz);
68 :     }
69 :     }
70 : jhr 1978
71 :     static struct {
72 :     bool isFloat;
73 :     unsigned int sizeb;
74 :     } NrrdTypeInfo[nrrdTypeLast] = {
75 :     [nrrdTypeDefault] = {false, 0}, /* 0: signifies "determine output type for me" */
76 :     [nrrdTypeChar] = {false, 1}, /* 1: signed 1-byte integer */
77 :     [nrrdTypeUChar] = {false, 1}, /* 2: unsigned 1-byte integer */
78 :     [nrrdTypeShort] = {false, 2}, /* 3: signed 2-byte integer */
79 :     [nrrdTypeUShort] = {false, 2}, /* 4: unsigned 2-byte integer */
80 :     [nrrdTypeInt] = {false, 4}, /* 5: signed 4-byte integer */
81 :     [nrrdTypeUInt] = {false, 4}, /* 6: unsigned 4-byte integer */
82 :     [nrrdTypeLLong] = {false, 8}, /* 7: signed 8-byte integer */
83 :     [nrrdTypeULLong] = {false, 8}, /* 8: unsigned 8-byte integer */
84 :     [nrrdTypeFloat] = {true, 4}, /* 9: 4-byte floating point */
85 :     [nrrdTypeDouble] = {true, 8}, /* 10: 8-byte floating point */
86 :     [nrrdTypeBlock] = {false, 0}, /* 11: size user defined at run time; MUST BE LAST */
87 :     };
88 :    
89 :     //! Check that a nrrd has the expected structure for loading into a dynamic sequence
90 :     //! \param wrld the world; used to report errors
91 :     //! \param nin the nrrd to check
92 :     //! \param nDims the number of dimensions in the sequence elements
93 :     //! \param dims the array of sequence element dimensions
94 :     //! \return the number of values per element, or zero on error
95 :     static unsigned int CheckNrrd (
96 :     WorldPrefix_t *wrld,
97 :     Nrrd *nin,
98 :     unsigned int nDims,
99 :     unsigned int *dims)
100 :     {
101 :    
102 :     // compute the expected number of values per sequence element
103 :     unsigned int nValuesPerElem = 1;
104 :     for (unsigned int i = 0; i < nDims; i++) {
105 :     nValuesPerElem *= dims[i];
106 :     }
107 :    
108 :     // check the structure of the nrrd file
109 :     if (nin->spaceDim != 1) {
110 :     Diderot_Error (wrld, "unexpected number of axes in nrrd; expected 1, found %d\n",
111 :     nin->spaceDim);
112 :     return 0;
113 :     }
114 :     if (nin->dim - 1 != nDims) {
115 :     Diderot_Error (wrld, "unexpected nrrd dimension; expected %d, found %d\n",
116 :     nDims, nin->dim-1);
117 :     return 0;
118 :     }
119 :     for (unsigned int i = 0; i < nDims; i++) {
120 :     if (dims[i] != nin->axis[i+1].size) {
121 :     Diderot_Error (wrld, "nrrd shape does not match expected structure\n");
122 :     return 0;
123 :     }
124 :     }
125 : jhr 1979 if (NrrdTypeInfo[nin->type].sizeb == 0) {
126 : jhr 1978 Diderot_Error (wrld, "bogus element type %d in nrrd\n", nin->type);
127 :     return 0;
128 :     }
129 :    
130 :     return nValuesPerElem;
131 :     }
132 :    
133 : jhr 2033
134 : jhr 1978 //! load a dynamic sequence from a Nrrd file, where the sequence elements have real ground type.
135 :     //! \param wrld the world; used to report errors
136 :     //! \param nin the nrrd to check
137 :     //! \param nDims the number of dimensions in the sequence elements
138 :     //! \param dims the array of sequence element dimensions
139 :     //! \return the dynamic sequence, or zero on error
140 :     Diderot_DynSeq_t *Diderot_DynSeqLoadReal (
141 :     WorldPrefix_t *wrld,
142 :     Nrrd *nin,
143 :     unsigned int nDims,
144 :     unsigned int *dims)
145 :     {
146 :     unsigned int nValuesPerElem = CheckNrrd(wrld, nin, nDims, dims);
147 :     size_t elemSz = SIZEOF_DIDEROT_REAL * nValuesPerElem;
148 :    
149 :     if (nValuesPerElem == 0)
150 :     return (Diderot_DynSeq_t *)0;
151 :    
152 :     // get the number of elements
153 :     size_t nElems = nin->axis[0].size;
154 :    
155 :     // allocate the dynamic sequence
156 :     Diderot_DynSeq_t *seq = Diderot_DynSeqAlloc(elemSz, nElems);
157 :    
158 :     // initialize the sequence from the nrrd
159 : jhr 1979 if (! NrrdTypeInfo[nin->type].isFloat || (NrrdTypeInfo[nin->type].sizeb != SIZEOF_DIDEROT_REAL)) {
160 : jhr 1978 // this is the slow path; we have to convert values as they are copied from the nrrd
161 :     #if defined(DIDEROT_DOUBLE_PRECISION)
162 :     double (*loadFn)(const void *) = nrrdDLoad[nin->type];
163 :     #else
164 :     float (*loadFn)(const void *) = nrrdFLoad[nin->type];
165 :     #endif
166 :     Diderot_real_t *dst = (Diderot_real_t *)seq->data;
167 :     char *src = (char *)nin->data;
168 : jhr 1979 size_t srcElemSz = NrrdTypeInfo[nin->type].sizeb;
169 : jhr 1978 for (size_t i = 0; i < nElems * nValuesPerElem; i++) {
170 :     *dst++ = loadFn(src);
171 :     src += srcElemSz;
172 :     }
173 :     }
174 :     else {
175 :     // this is the fast path, where we can just do a bulk memcpy
176 :     memcpy (seq->data, nin->data, nElems * elemSz);
177 :     }
178 :    
179 :     return seq;
180 :    
181 :     }
182 :    
183 :    
184 : jhr 2033 //! load a dynamic sequence from a Nrrd file, where the sequence elements have real ground type.
185 :     //! \param wrld the world; used to report errors
186 :     //! \param name the name of the nrrd file
187 :     //! \param nDims the number of dimensions in the sequence elements
188 :     //! \param dims the array of sequence element dimensions
189 :     //! \return the dynamic sequence, or zero on error
190 :     Diderot_DynSeq_t *Diderot_DynSeqLoadRealFromFile (
191 :     WorldPrefix_t *wrld,
192 :     const char *name,
193 :     unsigned int nDims,
194 :     unsigned int *dims)
195 :     {
196 :     Nrrd *nin = Diderot_LoadNrrdFile (wrld, name);
197 :     if (nin == 0)
198 :     return 0;
199 :     else
200 :     return Diderot_DynSeqLoadReal(wrld, nin, nDims, dims);
201 :    
202 :     }
203 :    
204 :    
205 :    
206 : jhr 1978 //! load a dynamic sequence from a Nrrd file, where the sequence elements have int ground type.
207 :     //! \param wrld the world; used to report errors
208 :     //! \param nin the nrrd to check
209 :     //! \param nDims the number of dimensions in the sequence elements
210 :     //! \param dims the array of sequence element dimensions
211 :     //! \return the dynamic sequence, or zero on error
212 :     Diderot_DynSeq_t *Diderot_DynSeqLoadInt (
213 :     WorldPrefix_t *wrld,
214 :     Nrrd *nin,
215 :     unsigned int nDims,
216 :     unsigned int *dims)
217 :     {
218 :     unsigned int nValuesPerElem = CheckNrrd(wrld, nin, nDims, dims);
219 :     size_t elemSz = SIZEOF_DIDEROT_INT * nValuesPerElem;
220 :    
221 :     if (nValuesPerElem == 0)
222 :     return (Diderot_DynSeq_t *)0;
223 :    
224 : jhr 1979 if (NrrdTypeInfo[nin->type].isFloat) {
225 : jhr 1978 Diderot_Error (wrld, "expected integer element type for int sequence, but found %d\n", nin->type);
226 :     return 0;
227 :     }
228 :    
229 :     // get the number of elements
230 :     size_t nElems = nin->axis[0].size;
231 :    
232 :     // allocate the dynamic sequence
233 :     Diderot_DynSeq_t *seq = Diderot_DynSeqAlloc(elemSz, nElems);
234 :    
235 :     // initialize the sequence from the nrrd
236 : jhr 1979 if (NrrdTypeInfo[nin->type].sizeb != SIZEOF_DIDEROT_INT) {
237 : jhr 1978 // this is the slow path; we have to convert values as they are copied from the nrrd
238 :     int (*loadFn)(const void *) = nrrdILoad[nin->type];
239 :     Diderot_int_t *dst = (Diderot_int_t *)seq->data;
240 :     char *src = (char *)nin->data;
241 : jhr 1979 size_t srcElemSz = NrrdTypeInfo[nin->type].sizeb;
242 : jhr 1978 for (size_t i = 0; i < nElems * nValuesPerElem; i++) {
243 :     *dst++ = loadFn(src);
244 :     src += srcElemSz;
245 :     }
246 :     }
247 :     else {
248 :     // this is the fast path, where we can just do a bulk memcpy
249 :     memcpy (seq->data, nin->data, nElems * elemSz);
250 :     }
251 :    
252 :     return seq;
253 :    
254 :     }
255 :    
256 :    
257 : jhr 2033 //! load a dynamic sequence from a Nrrd file, where the sequence elements have int ground type.
258 :     //! \param wrld the world; used to report errors
259 :     //! \param name the name of the nrrd file
260 :     //! \param nDims the number of dimensions in the sequence elements
261 :     //! \param dims the array of sequence element dimensions
262 :     //! \return the dynamic sequence, or zero on error
263 :     Diderot_DynSeq_t *Diderot_DynSeqLoadIntFromFile (
264 :     WorldPrefix_t *wrld,
265 :     const char *name,
266 :     unsigned int nDims,
267 :     unsigned int *dims)
268 :     {
269 :     Nrrd *nin = Diderot_LoadNrrdFile (wrld, name);
270 :     if (nin == 0)
271 :     return 0;
272 :     else
273 :     return Diderot_DynSeqLoadInt(wrld, nin, nDims, dims);
274 :    
275 :     }
276 :    
277 :    
278 : jhr 1978 //! load a dynamic sequence from a Nrrd file, where the sequence elements have bool ground type.
279 :     //! \param wrld the world; used to report errors
280 :     //! \param nin the nrrd to check
281 :     //! \param nDims the number of dimensions in the sequence elements
282 :     //! \param dims the array of sequence element dimensions
283 :     //! \return the dynamic sequence, or zero on error
284 :     Diderot_DynSeq_t *Diderot_DynSeqLoadBool (
285 :     WorldPrefix_t *wrld,
286 :     Nrrd *nin,
287 :     unsigned int nDims,
288 :     unsigned int *dims)
289 :     {
290 :     unsigned int nValuesPerElem = CheckNrrd(wrld, nin, nDims, dims);
291 : jhr 1979 size_t elemSz = sizeof(bool) * nValuesPerElem;
292 : jhr 1978
293 :     if (nValuesPerElem == 0)
294 :     return (Diderot_DynSeq_t *)0;
295 :    
296 : jhr 1979 if (NrrdTypeInfo[nin->type].isFloat) {
297 : jhr 1978 Diderot_Error (wrld, "expected integer element type for bool sequence, but found %d\n", nin->type);
298 :     return 0;
299 :     }
300 :    
301 :     // get the number of elements
302 :     size_t nElems = nin->axis[0].size;
303 :    
304 :     // allocate the dynamic sequence
305 :     Diderot_DynSeq_t *seq = Diderot_DynSeqAlloc(elemSz, nElems);
306 :    
307 :     // initialize the sequence from the nrrd
308 : jhr 1979 if (NrrdTypeInfo[nin->type].sizeb != sizeof(bool)) {
309 : jhr 1978 // this is the slow path; we have to convert values as they are copied from the nrrd
310 :     int (*loadFn)(const void *) = nrrdILoad[nin->type];
311 :     bool *dst = (bool *)seq->data;
312 :     char *src = (char *)nin->data;
313 : jhr 1979 size_t srcElemSz = NrrdTypeInfo[nin->type].sizeb;
314 : jhr 1978 for (size_t i = 0; i < nElems * nValuesPerElem; i++) {
315 :     *dst++ = loadFn(src) ? true : false;
316 :     src += srcElemSz;
317 :     }
318 :     }
319 :     else {
320 :     // this is the fast path, where we can just do a bulk memcpy
321 :     memcpy (seq->data, nin->data, nElems * elemSz);
322 :     }
323 :    
324 :     return seq;
325 :    
326 :     }
327 : jhr 2033
328 :     //! load a dynamic sequence from a Nrrd file, where the sequence elements have bool ground type.
329 :     //! \param wrld the world; used to report errors
330 :     //! \param name the name of the nrrd file
331 :     //! \param nDims the number of dimensions in the sequence elements
332 :     //! \param dims the array of sequence element dimensions
333 :     //! \return the dynamic sequence, or zero on error
334 :     Diderot_DynSeq_t *Diderot_DynSeqLoadBoolFromFile (
335 :     WorldPrefix_t *wrld,
336 :     const char *name,
337 :     unsigned int nDims,
338 :     unsigned int *dims)
339 :     {
340 :     Nrrd *nin = Diderot_LoadNrrdFile (wrld, name);
341 :     if (nin == 0)
342 :     return 0;
343 :     else
344 :     return Diderot_DynSeqLoadBool(wrld, nin, nDims, dims);
345 :    
346 :     }

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0