Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/3rdparty/carotene/src/sub.cpp
16337 views
1
/*
2
* By downloading, copying, installing or using the software you agree to this license.
3
* If you do not agree to this license, do not download, install,
4
* copy or use the software.
5
*
6
*
7
* License Agreement
8
* For Open Source Computer Vision Library
9
* (3-clause BSD License)
10
*
11
* Copyright (C) 2014, NVIDIA Corporation, all rights reserved.
12
* Third party copyrights are property of their respective owners.
13
*
14
* Redistribution and use in source and binary forms, with or without modification,
15
* are permitted provided that the following conditions are met:
16
*
17
* * Redistributions of source code must retain the above copyright notice,
18
* this list of conditions and the following disclaimer.
19
*
20
* * Redistributions in binary form must reproduce the above copyright notice,
21
* this list of conditions and the following disclaimer in the documentation
22
* and/or other materials provided with the distribution.
23
*
24
* * Neither the names of the copyright holders nor the names of the contributors
25
* may be used to endorse or promote products derived from this software
26
* without specific prior written permission.
27
*
28
* This software is provided by the copyright holders and contributors "as is" and
29
* any express or implied warranties, including, but not limited to, the implied
30
* warranties of merchantability and fitness for a particular purpose are disclaimed.
31
* In no event shall copyright holders or contributors be liable for any direct,
32
* indirect, incidental, special, exemplary, or consequential damages
33
* (including, but not limited to, procurement of substitute goods or services;
34
* loss of use, data, or profits; or business interruption) however caused
35
* and on any theory of liability, whether in contract, strict liability,
36
* or tort (including negligence or otherwise) arising in any way out of
37
* the use of this software, even if advised of the possibility of such damage.
38
*/
39
40
#include "common.hpp"
41
#include "vtransform.hpp"
42
43
namespace CAROTENE_NS {
44
45
#ifdef CAROTENE_NEON
46
47
namespace {
48
49
template <typename T, typename WT>
50
struct SubWrap
51
{
52
typedef T type;
53
54
void operator() (const typename internal::VecTraits<T>::vec128 & v_src0,
55
const typename internal::VecTraits<T>::vec128 & v_src1,
56
typename internal::VecTraits<T>::vec128 & v_dst) const
57
{
58
v_dst = internal::vsubq(v_src0, v_src1);
59
}
60
61
void operator() (const typename internal::VecTraits<T>::vec64 & v_src0,
62
const typename internal::VecTraits<T>::vec64 & v_src1,
63
typename internal::VecTraits<T>::vec64 & v_dst) const
64
{
65
v_dst = internal::vsub(v_src0, v_src1);
66
}
67
68
void operator() (const T * src0, const T * src1, T * dst) const
69
{
70
dst[0] = (T)((WT)src0[0] - (WT)src1[0]);
71
}
72
};
73
74
template <typename T, typename WT>
75
struct SubSaturate
76
{
77
typedef T type;
78
79
void operator() (const typename internal::VecTraits<T>::vec128 & v_src0,
80
const typename internal::VecTraits<T>::vec128 & v_src1,
81
typename internal::VecTraits<T>::vec128 & v_dst) const
82
{
83
v_dst = internal::vqsubq(v_src0, v_src1);
84
}
85
86
void operator() (const typename internal::VecTraits<T>::vec64 & v_src0,
87
const typename internal::VecTraits<T>::vec64 & v_src1,
88
typename internal::VecTraits<T>::vec64 & v_dst) const
89
{
90
v_dst = internal::vqsub(v_src0, v_src1);
91
}
92
93
void operator() (const T * src0, const T * src1, T * dst) const
94
{
95
dst[0] = internal::saturate_cast<T>((WT)src0[0] - (WT)src1[0]);
96
}
97
};
98
99
} // namespace
100
101
#endif
102
103
void sub(const Size2D &size,
104
const u8 * src0Base, ptrdiff_t src0Stride,
105
const u8 * src1Base, ptrdiff_t src1Stride,
106
u8 *dstBase, ptrdiff_t dstStride,
107
CONVERT_POLICY policy)
108
{
109
internal::assertSupportedConfiguration();
110
#ifdef CAROTENE_NEON
111
if (policy == CONVERT_POLICY_SATURATE)
112
{
113
internal::vtransform(size,
114
src0Base, src0Stride,
115
src1Base, src1Stride,
116
dstBase, dstStride,
117
SubSaturate<u8, s16>());
118
}
119
else
120
{
121
internal::vtransform(size,
122
src0Base, src0Stride,
123
src1Base, src1Stride,
124
dstBase, dstStride,
125
SubWrap<u8, s16>());
126
}
127
#else
128
(void)size;
129
(void)src0Base;
130
(void)src0Stride;
131
(void)src1Base;
132
(void)src1Stride;
133
(void)dstBase;
134
(void)dstStride;
135
(void)policy;
136
#endif
137
}
138
139
void sub(const Size2D &size,
140
const u8 * src0Base, ptrdiff_t src0Stride,
141
const u8 * src1Base, ptrdiff_t src1Stride,
142
s16 *dstBase, ptrdiff_t dstStride,
143
CONVERT_POLICY)
144
{
145
internal::assertSupportedConfiguration();
146
#ifdef CAROTENE_NEON
147
size_t roiw32 = size.width >= 31 ? size.width - 31 : 0;
148
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
149
150
for (size_t i = 0; i < size.height; ++i)
151
{
152
const u8 * src0 = internal::getRowPtr(src0Base, src0Stride, i);
153
const u8 * src1 = internal::getRowPtr(src1Base, src1Stride, i);
154
u16 * dstu16 = internal::getRowPtr((u16 *)dstBase, dstStride, i);
155
s16 * dst = internal::getRowPtr(dstBase, dstStride, i);
156
size_t j = 0;
157
158
for (; j < roiw32; j += 32)
159
{
160
internal::prefetch(src0 + j);
161
internal::prefetch(src1 + j);
162
uint8x16_t v_src00 = vld1q_u8(src0 + j), v_src01 = vld1q_u8(src0 + j + 16);
163
uint8x16_t v_src10 = vld1q_u8(src1 + j), v_src11 = vld1q_u8(src1 + j + 16);
164
vst1q_u16(dstu16 + j, vsubl_u8(vget_low_u8(v_src00), vget_low_u8(v_src10)));
165
vst1q_u16(dstu16 + j + 8, vsubl_u8(vget_high_u8(v_src00), vget_high_u8(v_src10)));
166
vst1q_u16(dstu16 + j + 16, vsubl_u8(vget_low_u8(v_src01), vget_low_u8(v_src11)));
167
vst1q_u16(dstu16 + j + 24, vsubl_u8(vget_high_u8(v_src01), vget_high_u8(v_src11)));
168
}
169
for (; j < roiw8; j += 8)
170
{
171
uint8x8_t v_src0 = vld1_u8(src0 + j);
172
uint8x8_t v_src1 = vld1_u8(src1 + j);
173
vst1q_u16(dstu16 + j, vsubl_u8(v_src0, v_src1));
174
}
175
176
for (; j < size.width; j++)
177
dst[j] = (s16)src0[j] - (s16)src1[j];
178
}
179
#else
180
(void)size;
181
(void)src0Base;
182
(void)src0Stride;
183
(void)src1Base;
184
(void)src1Stride;
185
(void)dstBase;
186
(void)dstStride;
187
#endif
188
}
189
190
void sub(const Size2D &size,
191
const u8 * src0Base, ptrdiff_t src0Stride,
192
const u8 * src1Base, ptrdiff_t src1Stride,
193
f32 *dstBase, ptrdiff_t dstStride)
194
{
195
internal::assertSupportedConfiguration();
196
#ifdef CAROTENE_NEON
197
size_t roiw32 = size.width >= 31 ? size.width - 31 : 0;
198
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
199
200
for (size_t i = 0; i < size.height; ++i)
201
{
202
const u8 * src0 = internal::getRowPtr(src0Base, src0Stride, i);
203
const u8 * src1 = internal::getRowPtr(src1Base, src1Stride, i);
204
f32 * dst = internal::getRowPtr(dstBase, dstStride, i);
205
size_t j = 0;
206
207
for (; j < roiw32; j += 32)
208
{
209
internal::prefetch(src0 + j);
210
internal::prefetch(src1 + j);
211
uint8x16_t v_src00 = vld1q_u8(src0 + j), v_src01 = vld1q_u8(src0 + j + 16);
212
uint8x16_t v_src10 = vld1q_u8(src1 + j), v_src11 = vld1q_u8(src1 + j + 16);
213
int16x8_t vsl = vreinterpretq_s16_u16(vsubl_u8( vget_low_u8(v_src00), vget_low_u8(v_src10)));
214
int16x8_t vsh = vreinterpretq_s16_u16(vsubl_u8(vget_high_u8(v_src00), vget_high_u8(v_src10)));
215
216
vst1q_f32(dst + j + 0, vcvtq_f32_s32(vmovl_s16( vget_low_s16(vsl) )));
217
vst1q_f32(dst + j + 4, vcvtq_f32_s32(vmovl_s16( vget_high_s16(vsl) )));
218
vst1q_f32(dst + j + 8, vcvtq_f32_s32(vmovl_s16( vget_low_s16(vsh) )));
219
vst1q_f32(dst + j + 12, vcvtq_f32_s32(vmovl_s16( vget_high_s16(vsh) )));
220
221
vsl = vreinterpretq_s16_u16(vsubl_u8( vget_low_u8(v_src01), vget_low_u8(v_src11)));
222
vsh = vreinterpretq_s16_u16(vsubl_u8(vget_high_u8(v_src01), vget_high_u8(v_src11)));
223
224
vst1q_f32(dst + j + 16, vcvtq_f32_s32(vmovl_s16( vget_low_s16(vsl) )));
225
vst1q_f32(dst + j + 20, vcvtq_f32_s32(vmovl_s16( vget_high_s16(vsl) )));
226
vst1q_f32(dst + j + 24, vcvtq_f32_s32(vmovl_s16( vget_low_s16(vsh) )));
227
vst1q_f32(dst + j + 28, vcvtq_f32_s32(vmovl_s16( vget_high_s16(vsh) )));
228
}
229
for (; j < roiw8; j += 8)
230
{
231
uint8x8_t v_src0 = vld1_u8(src0 + j);
232
uint8x8_t v_src1 = vld1_u8(src1 + j);
233
234
int16x8_t vs = vreinterpretq_s16_u16(vsubl_u8(v_src0, v_src1));
235
vst1q_f32(dst + j + 0, vcvtq_f32_s32(vmovl_s16( vget_low_s16(vs) )));
236
vst1q_f32(dst + j + 4, vcvtq_f32_s32(vmovl_s16( vget_high_s16(vs) )));
237
}
238
for(; j < size.width; j++)
239
dst[j] = (f32)src0[j] - (f32)src1[j];
240
}
241
#else
242
(void)size;
243
(void)src0Base;
244
(void)src0Stride;
245
(void)src1Base;
246
(void)src1Stride;
247
(void)dstBase;
248
(void)dstStride;
249
#endif
250
}
251
252
void sub(const Size2D &size,
253
const u8 * src0Base, ptrdiff_t src0Stride,
254
const s16 * src1Base, ptrdiff_t src1Stride,
255
s16 *dstBase, ptrdiff_t dstStride,
256
CONVERT_POLICY policy)
257
{
258
internal::assertSupportedConfiguration();
259
#ifdef CAROTENE_NEON
260
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
261
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
262
263
for (size_t i = 0; i < size.height; ++i)
264
{
265
const u8 * src0 = internal::getRowPtr(src0Base, src0Stride, i);
266
const s16 * src1 = internal::getRowPtr(src1Base, src1Stride, i);
267
s16 * dst = internal::getRowPtr(dstBase, dstStride, i);
268
size_t j = 0;
269
270
if (policy == CONVERT_POLICY_SATURATE)
271
{
272
for (; j < roiw16; j += 16)
273
{
274
internal::prefetch(src0 + j);
275
internal::prefetch(src1 + j);
276
uint8x16_t v_src0 = vld1q_u8(src0 + j);
277
int16x8_t v_src00 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(v_src0)));
278
int16x8_t v_src01 = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(v_src0)));
279
int16x8_t v_src10 = vld1q_s16(src1 + j), v_src11 = vld1q_s16(src1 + j + 8);
280
int16x8_t v_dst0 = vqsubq_s16(v_src00, v_src10);
281
int16x8_t v_dst1 = vqsubq_s16(v_src01, v_src11);
282
vst1q_s16(dst + j, v_dst0);
283
vst1q_s16(dst + j + 8, v_dst1);
284
}
285
for (; j < roiw8; j += 8)
286
{
287
int16x8_t v_src0 = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(src0 + j)));
288
int16x8_t v_src1 = vld1q_s16(src1 + j);
289
int16x8_t v_dst = vqsubq_s16(v_src0, v_src1);
290
vst1q_s16(dst + j, v_dst);
291
}
292
293
for (; j < size.width; j++)
294
dst[j] = internal::saturate_cast<s16>((s32)src0[j] - (s32)src1[j]);
295
}
296
else
297
{
298
for (; j < roiw16; j += 16)
299
{
300
internal::prefetch(src0 + j);
301
internal::prefetch(src1 + j);
302
uint8x16_t v_src0 = vld1q_u8(src0 + j);
303
int16x8_t v_src00 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(v_src0)));
304
int16x8_t v_src01 = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(v_src0)));
305
int16x8_t v_src10 = vld1q_s16(src1 + j), v_src11 = vld1q_s16(src1 + j + 8);
306
int16x8_t v_dst0 = vsubq_s16(v_src00, v_src10);
307
int16x8_t v_dst1 = vsubq_s16(v_src01, v_src11);
308
vst1q_s16(dst + j, v_dst0);
309
vst1q_s16(dst + j + 8, v_dst1);
310
}
311
for (; j < roiw8; j += 8)
312
{
313
int16x8_t v_src0 = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(src0 + j)));
314
int16x8_t v_src1 = vld1q_s16(src1 + j);
315
int16x8_t v_dst = vsubq_s16(v_src0, v_src1);
316
vst1q_s16(dst + j, v_dst);
317
}
318
319
for (; j < size.width; j++)
320
dst[j] = (s16)((s32)src0[j] - (s32)src1[j]);
321
}
322
}
323
#else
324
(void)size;
325
(void)src0Base;
326
(void)src0Stride;
327
(void)src1Base;
328
(void)src1Stride;
329
(void)dstBase;
330
(void)dstStride;
331
(void)policy;
332
#endif
333
}
334
335
void sub(const Size2D &size,
336
const s16 * src0Base, ptrdiff_t src0Stride,
337
const u8 * src1Base, ptrdiff_t src1Stride,
338
s16 *dstBase, ptrdiff_t dstStride,
339
CONVERT_POLICY policy)
340
{
341
internal::assertSupportedConfiguration();
342
#ifdef CAROTENE_NEON
343
size_t roiw16 = size.width >= 15 ? size.width - 15 : 0;
344
size_t roiw8 = size.width >= 7 ? size.width - 7 : 0;
345
346
for (size_t i = 0; i < size.height; ++i)
347
{
348
const s16 * src0 = internal::getRowPtr(src0Base, src0Stride, i);
349
const u8 * src1 = internal::getRowPtr(src1Base, src1Stride, i);
350
s16 * dst = internal::getRowPtr(dstBase, dstStride, i);
351
size_t j = 0;
352
353
if (policy == CONVERT_POLICY_SATURATE)
354
{
355
for (; j < roiw16; j += 16)
356
{
357
internal::prefetch(src0 + j);
358
internal::prefetch(src1 + j);
359
int16x8_t v_src00 = vld1q_s16(src0 + j), v_src01 = vld1q_s16(src0 + j + 8);
360
uint8x16_t v_src1 = vld1q_u8(src1 + j);
361
int16x8_t v_src10 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(v_src1)));
362
int16x8_t v_src11 = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(v_src1)));
363
int16x8_t v_dst0 = vqsubq_s16(v_src00, v_src10);
364
int16x8_t v_dst1 = vqsubq_s16(v_src01, v_src11);
365
vst1q_s16(dst + j, v_dst0);
366
vst1q_s16(dst + j + 8, v_dst1);
367
}
368
for (; j < roiw8; j += 8)
369
{
370
int16x8_t v_src0 = vld1q_s16(src0 + j);
371
int16x8_t v_src1 = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(src1 + j)));
372
int16x8_t v_dst = vqsubq_s16(v_src0, v_src1);
373
vst1q_s16(dst + j, v_dst);
374
}
375
376
for (; j < size.width; j++)
377
dst[j] = internal::saturate_cast<s16>((s32)src0[j] - (s32)src1[j]);
378
}
379
else
380
{
381
for (; j < roiw16; j += 16)
382
{
383
internal::prefetch(src0 + j);
384
internal::prefetch(src1 + j);
385
int16x8_t v_src00 = vld1q_s16(src0 + j), v_src01 = vld1q_s16(src0 + j + 8);
386
uint8x16_t v_src1 = vld1q_u8(src1 + j);
387
int16x8_t v_src10 = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(v_src1)));
388
int16x8_t v_src11 = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(v_src1)));
389
int16x8_t v_dst0 = vsubq_s16(v_src00, v_src10);
390
int16x8_t v_dst1 = vsubq_s16(v_src01, v_src11);
391
vst1q_s16(dst + j, v_dst0);
392
vst1q_s16(dst + j + 8, v_dst1);
393
}
394
for (; j < roiw8; j += 8)
395
{
396
int16x8_t v_src0 = vld1q_s16(src0 + j);
397
int16x8_t v_src1 = vreinterpretq_s16_u16(vmovl_u8(vld1_u8(src1 + j)));
398
int16x8_t v_dst = vsubq_s16(v_src0, v_src1);
399
vst1q_s16(dst + j, v_dst);
400
}
401
402
for (; j < size.width; j++)
403
dst[j] = (s16)((s32)src0[j] - (s32)src1[j]);
404
}
405
}
406
#else
407
(void)size;
408
(void)src0Base;
409
(void)src0Stride;
410
(void)src1Base;
411
(void)src1Stride;
412
(void)dstBase;
413
(void)dstStride;
414
(void)policy;
415
#endif
416
}
417
418
void sub(const Size2D &size,
419
const s8 * src0Base, ptrdiff_t src0Stride,
420
const s8 * src1Base, ptrdiff_t src1Stride,
421
s8 *dstBase, ptrdiff_t dstStride,
422
CONVERT_POLICY policy)
423
{
424
internal::assertSupportedConfiguration();
425
#ifdef CAROTENE_NEON
426
if (policy == CONVERT_POLICY_SATURATE)
427
{
428
internal::vtransform(size,
429
src0Base, src0Stride,
430
src1Base, src1Stride,
431
dstBase, dstStride,
432
SubSaturate<s8, s16>());
433
}
434
else
435
{
436
internal::vtransform(size,
437
src0Base, src0Stride,
438
src1Base, src1Stride,
439
dstBase, dstStride,
440
SubWrap<s8, s16>());
441
}
442
#else
443
(void)size;
444
(void)src0Base;
445
(void)src0Stride;
446
(void)src1Base;
447
(void)src1Stride;
448
(void)dstBase;
449
(void)dstStride;
450
(void)policy;
451
#endif
452
}
453
454
void sub(const Size2D &size,
455
const s16 * src0Base, ptrdiff_t src0Stride,
456
const s16 * src1Base, ptrdiff_t src1Stride,
457
s16 *dstBase, ptrdiff_t dstStride,
458
CONVERT_POLICY policy)
459
{
460
internal::assertSupportedConfiguration();
461
#ifdef CAROTENE_NEON
462
if (policy == CONVERT_POLICY_SATURATE)
463
{
464
internal::vtransform(size,
465
src0Base, src0Stride,
466
src1Base, src1Stride,
467
dstBase, dstStride,
468
SubSaturate<s16, s32>());
469
}
470
else
471
{
472
internal::vtransform(size,
473
src0Base, src0Stride,
474
src1Base, src1Stride,
475
dstBase, dstStride,
476
SubWrap<s16, s32>());
477
}
478
#else
479
(void)size;
480
(void)src0Base;
481
(void)src0Stride;
482
(void)src1Base;
483
(void)src1Stride;
484
(void)dstBase;
485
(void)dstStride;
486
(void)policy;
487
#endif
488
}
489
490
void sub(const Size2D &size,
491
const u16 * src0Base, ptrdiff_t src0Stride,
492
const u16 * src1Base, ptrdiff_t src1Stride,
493
u16 *dstBase, ptrdiff_t dstStride,
494
CONVERT_POLICY policy)
495
{
496
internal::assertSupportedConfiguration();
497
#ifdef CAROTENE_NEON
498
if (policy == CONVERT_POLICY_SATURATE)
499
{
500
internal::vtransform(size,
501
src0Base, src0Stride,
502
src1Base, src1Stride,
503
dstBase, dstStride,
504
SubSaturate<u16, s32>());
505
}
506
else
507
{
508
internal::vtransform(size,
509
src0Base, src0Stride,
510
src1Base, src1Stride,
511
dstBase, dstStride,
512
SubWrap<u16, s32>());
513
}
514
#else
515
(void)size;
516
(void)src0Base;
517
(void)src0Stride;
518
(void)src1Base;
519
(void)src1Stride;
520
(void)dstBase;
521
(void)dstStride;
522
(void)policy;
523
#endif
524
}
525
526
void sub(const Size2D &size,
527
const s32 * src0Base, ptrdiff_t src0Stride,
528
const s32 * src1Base, ptrdiff_t src1Stride,
529
s32 *dstBase, ptrdiff_t dstStride,
530
CONVERT_POLICY policy)
531
{
532
internal::assertSupportedConfiguration();
533
#ifdef CAROTENE_NEON
534
if (policy == CONVERT_POLICY_SATURATE)
535
{
536
internal::vtransform(size,
537
src0Base, src0Stride,
538
src1Base, src1Stride,
539
dstBase, dstStride,
540
SubSaturate<s32, s64>());
541
}
542
else
543
{
544
internal::vtransform(size,
545
src0Base, src0Stride,
546
src1Base, src1Stride,
547
dstBase, dstStride,
548
SubWrap<s32, s64>());
549
}
550
#else
551
(void)size;
552
(void)src0Base;
553
(void)src0Stride;
554
(void)src1Base;
555
(void)src1Stride;
556
(void)dstBase;
557
(void)dstStride;
558
(void)policy;
559
#endif
560
}
561
562
void sub(const Size2D &size,
563
const u32 * src0Base, ptrdiff_t src0Stride,
564
const u32 * src1Base, ptrdiff_t src1Stride,
565
u32 *dstBase, ptrdiff_t dstStride,
566
CONVERT_POLICY policy)
567
{
568
internal::assertSupportedConfiguration();
569
#ifdef CAROTENE_NEON
570
if (policy == CONVERT_POLICY_SATURATE)
571
{
572
internal::vtransform(size,
573
src0Base, src0Stride,
574
src1Base, src1Stride,
575
dstBase, dstStride,
576
SubSaturate<u32, s64>());
577
}
578
else
579
{
580
internal::vtransform(size,
581
src0Base, src0Stride,
582
src1Base, src1Stride,
583
dstBase, dstStride,
584
SubWrap<u32, s64>());
585
}
586
#else
587
(void)size;
588
(void)src0Base;
589
(void)src0Stride;
590
(void)src1Base;
591
(void)src1Stride;
592
(void)dstBase;
593
(void)dstStride;
594
(void)policy;
595
#endif
596
}
597
598
void sub(const Size2D &size,
599
const f32 * src0Base, ptrdiff_t src0Stride,
600
const f32 * src1Base, ptrdiff_t src1Stride,
601
f32 *dstBase, ptrdiff_t dstStride)
602
{
603
internal::assertSupportedConfiguration();
604
#ifdef CAROTENE_NEON
605
internal::vtransform(size,
606
src0Base, src0Stride,
607
src1Base, src1Stride,
608
dstBase, dstStride,
609
SubWrap<f32, f32>());
610
#else
611
(void)size;
612
(void)src0Base;
613
(void)src0Stride;
614
(void)src1Base;
615
(void)src1Stride;
616
(void)dstBase;
617
(void)dstStride;
618
#endif
619
}
620
621
} // namespace CAROTENE_NS
622
623