Endianness of Android NDK

AndroidAndroid Ndk

Android Problem Overview


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?

Android Solutions


Solution 1 - Android

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 - Android

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 - Android

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 - Android

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.

Solution 5 - Android

bool isLittleEndian() {
    unsigned short word=0x0102;
    return *(char*)&word==2;
}

simple.

Solution 6 - Android

Android NDK has below macros which may be used to check at compile time:

#if defined(__LITTLE_ENDIAN_BITFIELD)
#  error "Arch is Little Endian"
#elif defined (__BIG_ENDIAN_BITFIELD)
#  error "Arch is Big Endian"
#endif

in your case you should assume Little-Endian and place below some-where in the Native source if any:

#if _BYTE_ORDER != _LITTLE_ENDIAN || defined (__BIG_ENDIAN_BITFIELD)
#  error "Big-Endian Arch is not supported"
#endif

Solution 7 - Android

I tried with the "lxgr" answer, and I got LITTLE_ENDIAN also.

But working with C++, I read some file with this info: 50 4B 03 04 14 00 00 00 08 00 55 8A F4 3C 9B AA ...

I read the first 4 bytes as UnsignedLong, and I get 67324752 which (in hexa) is:

4034B50

(the first 4 bits, but reversed, as if i was working on a BIG_ENDIAN arch )

So, probably the "System.out.println(ByteOrder.nativeOrder());" reffers to how to handle them in java, but working in c++ with the NDK, you will have to check yourself, here is some code to shrink endiannes (from long readed in BIG_ENDIAN):

long shrinkEndian(long value){
    long result = 0;
    result += (value & 4278190080) >> 24;
    result += (value & 16711680) >> 8;
    result += (value & 65280) << 8;
    result += (value & 255) << 24;

    return result;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMatrix BaiView Question on Stackoverflow
Solution 1 - AndroidlxgrView Answer on Stackoverflow
Solution 2 - AndroidmP.View Answer on Stackoverflow
Solution 3 - AndroidmihaipopescuView Answer on Stackoverflow
Solution 4 - AndroidAles TeskaView Answer on Stackoverflow
Solution 5 - AndroidNoAngelView Answer on Stackoverflow
Solution 6 - AndroidTop-MasterView Answer on Stackoverflow
Solution 7 - AndroidSebastian CorradiView Answer on Stackoverflow