1 /*===========================================================================
2 *
3 *                            PUBLIC DOMAIN NOTICE
4 *               National Center for Biotechnology Information
5 *
6 *  This software/database is a "United States Government Work" under the
7 *  terms of the United States Copyright Act.  It was written as part of
8 *  the author's official duties as a United States Government employee and
9 *  thus cannot be copyrighted.  This software/database is freely available
10 *  to the public for use. The National Library of Medicine and the U.S.
11 *  Government have not placed any restriction on its use or reproduction.
12 *
13 *  Although all reasonable efforts have been taken to ensure the accuracy
14 *  and reliability of the software and data, the NLM and the U.S.
15 *  Government do not and cannot warrant the performance or results that
16 *  may be obtained by using this software or data. The NLM and the U.S.
17 *  Government disclaim all warranties, express or implied, including
18 *  warranties of performance, merchantability or fitness for any particular
19 *  purpose.
20 *
21 *  Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26 
27 #include <compiler.h>
28 #include <math.h>
29 
30 typedef void (*math_f)(void *dst, const void *src, size_t elem_count);
31 typedef union self_t {
32     void *vp;
33     math_f f;
34 } self_t;
35 
F32_to_I8(void * Dst,const void * Src,size_t elem_count)36 static void F32_to_I8(void *Dst, const void *Src, size_t elem_count) {
37     int8_t *dst = Dst;
38     const float *src = Src;
39     int i;
40 
41     for (i = 0; i != elem_count; ++i)
42         dst[i] = (int8_t)FLOAT_FUNC(src[i]);
43 }
44 
F32_to_U8(void * Dst,const void * Src,size_t elem_count)45 static void F32_to_U8(void *Dst, const void *Src, size_t elem_count) {
46     uint8_t *dst = Dst;
47     const float *src = Src;
48     int i;
49 
50     for (i = 0; i != elem_count; ++i)
51         dst[i] = (uint8_t)FLOAT_FUNC(src[i]);
52 }
53 
F32_to_I16(void * Dst,const void * Src,size_t elem_count)54 static void F32_to_I16(void *Dst, const void *Src, size_t elem_count) {
55     int16_t *dst = Dst;
56     const float *src = Src;
57     int i;
58 
59     for (i = 0; i != elem_count; ++i)
60         dst[i] = (int16_t)FLOAT_FUNC(src[i]);
61 }
62 
F32_to_U16(void * Dst,const void * Src,size_t elem_count)63 static void F32_to_U16(void *Dst, const void *Src, size_t elem_count) {
64     uint16_t *dst = Dst;
65     const float *src = Src;
66     int i;
67 
68     for (i = 0; i != elem_count; ++i)
69         dst[i] = (uint16_t)FLOAT_FUNC(src[i]);
70 }
71 
F32_to_I32(void * Dst,const void * Src,size_t elem_count)72 static void F32_to_I32(void *Dst, const void *Src, size_t elem_count) {
73     int32_t *dst = Dst;
74     const float *src = Src;
75     int i;
76 
77     for (i = 0; i != elem_count; ++i)
78         dst[i] = (int32_t)FLOAT_FUNC(src[i]);
79 }
80 
F32_to_U32(void * Dst,const void * Src,size_t elem_count)81 static void F32_to_U32(void *Dst, const void *Src, size_t elem_count) {
82     uint32_t *dst = Dst;
83     const float *src = Src;
84     int i;
85 
86     for (i = 0; i != elem_count; ++i)
87         dst[i] = (uint32_t)FLOAT_FUNC(src[i]);
88 }
89 
F32_to_I64(void * Dst,const void * Src,size_t elem_count)90 static void F32_to_I64(void *Dst, const void *Src, size_t elem_count) {
91     int64_t *dst = Dst;
92     const float *src = Src;
93     int i;
94 
95     for (i = 0; i != elem_count; ++i)
96         dst[i] = (int64_t)FLOAT_FUNC(src[i]);
97 }
98 
F32_to_U64(void * Dst,const void * Src,size_t elem_count)99 static void F32_to_U64(void *Dst, const void *Src, size_t elem_count) {
100     uint64_t *dst = Dst;
101     const float *src = Src;
102     int i;
103 
104     for (i = 0; i != elem_count; ++i)
105         dst[i] = (uint64_t)FLOAT_FUNC(src[i]);
106 }
107 
F32_to_F32(void * Dst,const void * Src,size_t elem_count)108 static void F32_to_F32(void *Dst, const void *Src, size_t elem_count) {
109     float *dst = Dst;
110     const float *src = Src;
111     int i;
112 
113     for (i = 0; i != elem_count; ++i)
114         dst[i] = FLOAT_FUNC(src[i]);
115 }
116 
F32_to_F64(void * Dst,const void * Src,size_t elem_count)117 static void F32_to_F64(void *Dst, const void *Src, size_t elem_count) {
118     double *dst = Dst;
119     const float *src = Src;
120     int i;
121 
122     for (i = 0; i != elem_count; ++i)
123         dst[i] = FLOAT_FUNC(src[i]);
124 }
125 
F64_to_I8(void * Dst,const void * Src,size_t elem_count)126 static void F64_to_I8(void *Dst, const void *Src, size_t elem_count) {
127     int8_t *dst = Dst;
128     const double *src = Src;
129     int i;
130 
131     for (i = 0; i != elem_count; ++i)
132         dst[i] = (int8_t)DOUBLE_FUNC(src[i]);
133 }
134 
F64_to_U8(void * Dst,const void * Src,size_t elem_count)135 static void F64_to_U8(void *Dst, const void *Src, size_t elem_count) {
136     uint8_t *dst = Dst;
137     const double *src = Src;
138     int i;
139 
140     for (i = 0; i != elem_count; ++i)
141         dst[i] = (uint8_t)DOUBLE_FUNC(src[i]);
142 }
143 
F64_to_I16(void * Dst,const void * Src,size_t elem_count)144 static void F64_to_I16(void *Dst, const void *Src, size_t elem_count) {
145     int16_t *dst = Dst;
146     const double *src = Src;
147     int i;
148 
149     for (i = 0; i != elem_count; ++i)
150         dst[i] = (int16_t)DOUBLE_FUNC(src[i]);
151 }
152 
F64_to_U16(void * Dst,const void * Src,size_t elem_count)153 static void F64_to_U16(void *Dst, const void *Src, size_t elem_count) {
154     uint16_t *dst = Dst;
155     const double *src = Src;
156     int i;
157 
158     for (i = 0; i != elem_count; ++i)
159         dst[i] = (uint16_t)DOUBLE_FUNC(src[i]);
160 }
161 
F64_to_I32(void * Dst,const void * Src,size_t elem_count)162 static void F64_to_I32(void *Dst, const void *Src, size_t elem_count) {
163     int32_t *dst = Dst;
164     const double *src = Src;
165     int i;
166 
167     for (i = 0; i != elem_count; ++i)
168         dst[i] = (int32_t)DOUBLE_FUNC(src[i]);
169 }
170 
F64_to_U32(void * Dst,const void * Src,size_t elem_count)171 static void F64_to_U32(void *Dst, const void *Src, size_t elem_count) {
172     uint32_t *dst = Dst;
173     const double *src = Src;
174     int i;
175 
176     for (i = 0; i != elem_count; ++i)
177         dst[i] = (uint32_t)DOUBLE_FUNC(src[i]);
178 }
179 
F64_to_I64(void * Dst,const void * Src,size_t elem_count)180 static void F64_to_I64(void *Dst, const void *Src, size_t elem_count) {
181     int64_t *dst = Dst;
182     const double *src = Src;
183     int i;
184 
185     for (i = 0; i != elem_count; ++i)
186         dst[i] = (int64_t)DOUBLE_FUNC(src[i]);
187 }
188 
F64_to_U64(void * Dst,const void * Src,size_t elem_count)189 static void F64_to_U64(void *Dst, const void *Src, size_t elem_count) {
190     uint64_t *dst = Dst;
191     const double *src = Src;
192     int i;
193 
194     for (i = 0; i != elem_count; ++i)
195         dst[i] = (uint64_t)DOUBLE_FUNC(src[i]);
196 }
197 
F64_to_F32(void * Dst,const void * Src,size_t elem_count)198 static void F64_to_F32(void *Dst, const void *Src, size_t elem_count) {
199     float *dst = Dst;
200     const double *src = Src;
201     int i;
202 
203     for (i = 0; i != elem_count; ++i)
204         dst[i] = (float)DOUBLE_FUNC(src[i]);
205 }
206 
F64_to_F64(void * Dst,const void * Src,size_t elem_count)207 static void F64_to_F64(void *Dst, const void *Src, size_t elem_count) {
208     double *dst = Dst;
209     const double *src = Src;
210     int i;
211 
212     for (i = 0; i != elem_count; ++i)
213         dst[i] = DOUBLE_FUNC(src[i]);
214 }
215 
216 static
array_func(void * Self,const VXformInfo * info,void * dst,const void * src,uint64_t num_elements)217 rc_t CC array_func(
218                 void *Self,
219                 const VXformInfo *info,
220                 void *dst,
221                 const void *src,
222                 uint64_t num_elements
223                 )
224 {
225     self_t hack;
226 
227     hack.vp = Self;
228     hack.f(dst, src, ( size_t ) num_elements);
229     return 0;
230 }
231 
factory(const void * self,const VXfactInfo * info,VFuncDesc * rslt,const VFactoryParams * cp,const VFunctionParams * dp)232 static rc_t factory( const void *self, const VXfactInfo *info,
233     VFuncDesc *rslt, const VFactoryParams *cp, const VFunctionParams *dp )
234 {
235     VTypedesc src_desc;
236     rc_t rc;
237     self_t hack;
238 
239     rc = VSchemaDescribeTypedecl(info->schema, &src_desc, &dp->argv[0].fd.td);
240     if (rc)
241         return rc;
242 
243     rslt->variant = vftArray;
244     rslt->u.af = array_func;
245 
246     switch (src_desc.intrinsic_bits) {
247     case 32:
248         switch (info->fdesc.desc.domain) {
249         case vtdInt:
250             switch (info->fdesc.desc.intrinsic_bits) {
251             case 8:
252                 hack.f = F32_to_I8;
253                 break;
254             case 16:
255                 hack.f = F32_to_I16;
256                 break;
257             case 32:
258                 hack.f = F32_to_I32;
259                 break;
260             case 64:
261                 hack.f = F32_to_I64;
262                 break;
263             default:
264                 return RC(rcVDB, rcFunction, rcConstructing, rcParam, rcInvalid);
265             }
266             break;
267         case vtdUint:
268             switch (info->fdesc.desc.intrinsic_bits) {
269             case 8:
270                 hack.f = F32_to_U8;
271                 break;
272             case 16:
273                 hack.f = F32_to_U16;
274                 break;
275             case 32:
276                 hack.f = F32_to_U32;
277                 break;
278             case 64:
279                 hack.f = F32_to_U64;
280                 break;
281             default:
282                 return RC(rcVDB, rcFunction, rcConstructing, rcParam, rcInvalid);
283             }
284             break;
285         case vtdFloat:
286             switch (info->fdesc.desc.intrinsic_bits) {
287             case 32:
288                 hack.f = F32_to_F32;
289                 break;
290             case 64:
291                 hack.f = F32_to_F64;
292                 break;
293             default:
294                 return RC(rcVDB, rcFunction, rcConstructing, rcParam, rcInvalid);
295             }
296             break;
297         default:
298             return RC(rcVDB, rcFunction, rcConstructing, rcParam, rcInvalid);
299         }
300         break;
301     case 64:
302         switch (info->fdesc.desc.domain) {
303         case vtdInt:
304             switch (info->fdesc.desc.intrinsic_bits) {
305             case 8:
306                 hack.f = F64_to_I8;
307                 break;
308             case 16:
309                 hack.f = F64_to_I16;
310                 break;
311             case 32:
312                 hack.f = F64_to_I32;
313                 break;
314             case 64:
315                 hack.f = F64_to_I64;
316                 break;
317             default:
318                 return RC(rcVDB, rcFunction, rcConstructing, rcParam, rcInvalid);
319             }
320             break;
321         case vtdUint:
322             switch (info->fdesc.desc.intrinsic_bits) {
323             case 8:
324                 hack.f = F64_to_U8;
325                 break;
326             case 16:
327                 hack.f = F64_to_U16;
328                 break;
329             case 32:
330                 hack.f = F64_to_U32;
331                 break;
332             case 64:
333                 hack.f = F64_to_U64;
334                 break;
335             default:
336                 return RC(rcVDB, rcFunction, rcConstructing, rcParam, rcInvalid);
337             }
338             break;
339         case vtdFloat:
340             switch (info->fdesc.desc.intrinsic_bits) {
341             case 32:
342                 hack.f = F64_to_F32;
343                 break;
344             case 64:
345                 hack.f = F64_to_F64;
346                 break;
347             default:
348                 return RC(rcVDB, rcFunction, rcConstructing, rcParam, rcInvalid);
349             }
350             break;
351         default:
352             return RC(rcVDB, rcFunction, rcConstructing, rcParam, rcInvalid);
353         }
354         break;
355     default:
356         return RC(rcVDB, rcFunction, rcConstructing, rcParam, rcInvalid);
357     }
358     rslt->self = hack.vp;
359     return 0;
360 }
361 
362