Friday, September 21, 2012

Endianness



In this series of posts dedicated to image file, the endianness is one of the parameters available in the Import dialog box. What is this strange 'little-endian byte order'?

1- Let's start with an example...

Import the image 'importEndianness.raw' [Link] with the function File > Import > Raw... as a '16-bit Unsigned' image of size 256 x 256 and you'll get a black image. If you hover the image with the mouse pointer, all the pixels have a value of 43981 which is displayed in the main ImageJ panel (Fig.1).

Fig.1: Import of a raw image with big endian byte order. The pixel value is 4398110 (ABCD16).

 Note: The decimal number 4398110 corresponds in hexadecimal to ABCD16.

Now, repeat the same import BUT check the 'Little-endian byte order' in the import dialog box, the same black window is diplayed however, the pixel value is now 52651 corresponding to a hexadecimal number of CDAB16 (Fig.2).

Fig.2: Import of the same raw image by  checking the 'little-endian byte order' option. The pixel value is now 52651 corresponding to CDAB16.

2- Little- and Big-endian? What does it mean?

In a file, the numbers are stored as bytes, thus, a 16-bit or 32-bit number must be splitted in 2 of 4 bytes before being put in the file. There is two different ways to do this job.
The first family of computers (e.g. ARM processors used by the smartphones) stores the bytes of a number from left to right as shown in the example of Fig.3 with the hexadecimal number 0807B7A016. This is called Big Endian because the first byte (byte 0 in Fig.3) is the most significant.
Fig 3: Big endian byte order


... whereas in the other family (x86 processor in every PC computers), the storage is done from right to left (Fig.4). This is called Little Endian and the first byte is now the least significant.

Fig4: Little endian byte order
Note: ImageJ runs on top of a virtual processor called 'Java Virtual Machine' and as indicated by its name acts as a virtual computer with its own virtual processor which belongs to the family of the 'Big Endian'.
In our previous example, the image containing only pixel values of ABCD16 was saved as a 'big-endian' byte order. Thus, when you import it as a 'little-endian byte ordered' file, the byte containing CD16 (the least significant byte) is put first and AB16 in second position explaining why we get a new value of CDAB16.

3- When I import an unknown image file, how do I know if I add a problem of endianness?

First, keep in mind that ImageJ is a big-endian program and by default, import the raw file using a big endian byte order. Thus, if you know which computer (processor family) and which program was used to save your image,  you can determine the byte order and decide to (un)check the 'litte-endian byte order' in the import dialog box.
Example #1: The computer belongs to the x86 family (e.g. an AMD or Intel processor) and the program was written in language C/C++, thus, your image is saved with a little-endian  byte order.
Example #2: The computer belongs to the x86 family but the program is written in Java and consequently runs on top of a big endian Java Virtual Machine. Thus, the image will be saved as a big endian file...
Second, you have no clue about the computer and/or the used program, you have to check both options. In most cases, when you use the wrong byte order, the image appears noisy and it is very difficult to recognize some features in the displayed image (Fig.5).

Fig.5: Raw image saved with a big-endian byte order (left) imported as a (wrong) little-endian byte order (right).

4- Links

  • Series of posts Image File [TOC]
  • Crazybiocomputing mini-games levels #8 and 9 [Link]

No comments:

Post a Comment