Endianness of Android NDK

后端 未结 7 959
生来不讨喜
生来不讨喜 2020-12-13 08:26

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

相关标签:
7条回答
  • 2020-12-13 08:46

    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.

    0 讨论(0)
  • 2020-12-13 08:47

    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
    
    0 讨论(0)
  • 2020-12-13 08:55

    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.

    0 讨论(0)
  • 2020-12-13 08:55
    bool isLittleEndian() {
        unsigned short word=0x0102;
        return *(char*)&word==2;
    }
    

    simple.

    0 讨论(0)
  • 2020-12-13 08:56

    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.

    0 讨论(0)
  • 2020-12-13 09:04

    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;
    }
    
    0 讨论(0)
提交回复
热议问题