Here is simple binarization function
void binarize(void *output, const void *input, int begin, int end, uint8_t threshold) {
#ifdef __ARM_NEON__
uint8x16_t thresholdVector = vdupq_n_u8(threshold);
uint8x16_t highValueVector = vdupq_n_u8(255);
uint8x16_t* __restrict inputVector = (uint8x16_t*)input;
uint8x16_t* __restrict outputVector = (uint8x16_t*)output;
for ( ; begin < end; begin += 16, ++inputVector, ++outputVector) {
*outputVector = (*inputVector > thresholdVector) & highValueVector;
}
#endif
}
It works fine on iOS. However when I'm compiling it for Android it gives me an error:
error: invalid operands of types 'uint8x16_t {aka __vector(16) __builtin_neon_uqi}' and 'uint8x16_t {aka __vector(16) __builtin_neon_uqi}' to binary 'operator>'
I use this flag in Android.mk to enable NEON:
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
LOCAL_ARM_NEON := true
endif
The difference comes because of different compilers. For iOS you are compiling with Clang but for Android you are building the code with GCC (unless you override the defaults).
GCC is much more stupid about vector types and could not use them with C/C++ operators like >
or &
. So you have two basic options:
Try to compile with Clang from the latest Android NDK r8c
Put NDK_TOOLCHAIN_VERSION=clang3.1
to your Application.mk
for this.
vld1q_u8
for load, vst1q_u8
for store, vcgtq_u8
for operator >
and vandq_u8
for operator &