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.1to yourApplication.mkfor this.vld1q_u8for load,vst1q_u8for store,vcgtq_u8foroperator >andvandq_u8foroperator &