Endianness of Android NDK
I'm working with my new app which processed captured image from cellphone camera. My phone is Nexus S, 2.3.4.
I create a ARGB_8888 Bitmap with captured data. I know the ndk image lib, but it's only support 2.2 and above. So I pass the int[] of Bitmap to NDK and found the color byte order is little-endian.
I searched the wiki and found arm architecture is bi-endian. http://en.wikipedia.org/wiki/Endianness#Bi-endian_hardware
My question is if arm is bi-endian, how to judge the byte order in specific device? Should I test the byte order every time before access the data?
Solution 1:
Directly from my Nexus S:
> import java.nio.*;
> System.out.println(ByteOrder.nativeOrder());
LITTLE_ENDIAN
There should also be some way to get the ordering in the NDK.
Solution 2:
Yes most cpus bi-endian, but most end user operating systems in use today choose to use the cpus in little-endian. Along those lines, ARM can operate in both as a convenience, its actual default after ARM 3 is little-endianess which is the endian mode it starts up in. I think one can safely assume that all Android devices are little endian, otherwise it would be extra work if different android devices were a mixture of endianess.
Because network byte order is big-endian, it can be helpful to convert any format you plan on using for data interchange to network byte order. Again, though, Mac OS X on Intel, Windows, iOS and Android are little-endian, so you might just code up structures with the native endianness and hope the next great OS you want to port data to doesn't go big-endian.
Solution 3:
ARM processors (on which some Android is running) supports both endian formats.
In NDK-ROOT/platforms/android-[x]/arch-arm/usr/include/machine/endian.h you can find:
#ifdef __ARMEB__
#define _BYTE_ORDER _BIG_ENDIAN
#else
#define _BYTE_ORDER _LITTLE_ENDIAN
#endif
__ARMEB__
is defined by the gcc compiler when using the -mbig-endian
ARM option.
Even if most Android architectures are using little endian by default you shouldn't take this for granted and for portability reasons your native code should be able to handle both endiannes.
To do that you should #include <endian.h>
and check BYTE_ORDER
to architecture your code properly.
Solution 4:
To provide very straightforward answer, here is a list:
- armeabi: LITTLE_ENDIAN
- armeabi-v7a: LITTLE_ENDIAN
- arm64-v8a: LITTLE_ENDIAN
- mips: LITTLE_ENDIAN
- mips64: LITTLE_ENDIAN
- x86: LITTLE_ENDIAN
- x86_64: LITTLE_ENDIAN
... as of Android API level 21.