We may use FFmpeg for testing the different pixel formats.
The conclusion are:
- There is no bit endianness, only bytes endianness.
- The endianness is relevant when the base elements is 2 bytes (
uint16).
Little endian: bytes order of uint16 element is: [LSB, MSB].
Bit endian: bytes order of uint16 element is: [MSB, LSB].
Executing FFmpeg CLI commands for testing:
Start with rgb24 for example:
ffmpeg -y -lavfi color=red:size=8x8:rate=1:duration=1 -pix_fmt rgb24 -f rawvideo red.raw
ffmpeg -y -lavfi color=0x00FF00:size=8x8:rate=1:duration=1 -pix_fmt rgb24 -f rawvideo green.raw
ffmpeg -y -lavfi color=blue:size=8x8:rate=1:duration=1 -pix_fmt rgb24 -f rawvideo blue.raw
Use some hex viewer like HxD for inspecting the raw file content.
red.raw FF 00 00 FF 00 00...
blue.raw 00 FF 00 00 FF 00...
green.raw 00 00 FF 00 00 FF...
rgba pixel format:
ffmpeg -y -lavfi color=red:size=8x8:rate=1:duration=1 -pix_fmt rgba -f rawvideo red.raw
ffmpeg -y -lavfi color=0x00FF00:size=8x8:rate=1:duration=1 -pix_fmt rgba -f rawvideo green.raw
ffmpeg -y -lavfi color=blue:size=8x8:rate=1:duration=1 -pix_fmt rgba -f rawvideo blue.raw
r: FF 00 00 FF
g: 00 FF 00 FF
b: 00 00 FF FF
The FFmpeg convention the order of the bytes.
We can't say if the naming applies little or big endian.
The endianness is relevant when using uint16 components (not uint8 components).
rgba pixel format:
ffmpeg -y -lavfi color=red:size=8x8:rate=1:duration=1 -pix_fmt rgba -f rawvideo red.raw
ffmpeg -y -lavfi color=0x00FF00:size=8x8:rate=1:duration=1 -pix_fmt rgba -f rawvideo green.raw
ffmpeg -y -lavfi color=blue:size=8x8:rate=1:duration=1 -pix_fmt rgba -f rawvideo blue.raw
r: FF 00 00 FF
g: 00 FF 00 FF
b: 00 00 FF FF
A then R then G then B then A...
We may refer rgba as RGBA32BE, but it's too confusing...
rgb555le pixel format:
ffmpeg -y -lavfi color=red:size=8x8:rate=1:duration=1 -pix_fmt rgb555le -f rawvideo red.raw
ffmpeg -y -lavfi color=0x00FF00:size=8x8:rate=1:duration=1 -pix_fmt rgb555le -f rawvideo green.raw
ffmpeg -y -lavfi color=blue:size=8x8:rate=1:duration=1 -pix_fmt rgb555le -f rawvideo blue.raw
r: 00 7C 00 7C
g: E0 03 E0 03
b: 1F 00 1F 00
We may also check the lower bit (for bits ordering):
Set the color to 8 so after shifting the value be 1.
ffmpeg -y -lavfi color=0x000008:size=8x8:rate=1:duration=1 -pix_fmt rgb555le -f rawvideo red.raw
ffmpeg -y -lavfi color=0x000800:size=8x8:rate=1:duration=1 -pix_fmt rgb555le -f rawvideo green.raw
ffmpeg -y -lavfi color=0x080000:size=8x8:rate=1:duration=1 -pix_fmt rgb555le -f rawvideo blue.raw
r: 01 00 01 00 2 bytes in bits: 00000001 00000000
g: 20 00 20 00 2 bytes in bits: 00100000 00000000
b: 00 04 00 04 2 bytes in bits: 00000000 00000100
rgb555be pixel format:
ffmpeg -y -lavfi color=red:size=8x8:rate=1:duration=1 -pix_fmt rgb555be -f rawvideo red.raw
ffmpeg -y -lavfi color=0x00FF00:size=8x8:rate=1:duration=1 -pix_fmt rgb555be -f rawvideo green.raw
ffmpeg -y -lavfi color=blue:size=8x8:rate=1:duration=1 -pix_fmt rgb555be -f rawvideo blue.raw
r: 7C 00 7C 00
g: 03 E0 03 E0
b: 00 1F 00 1F
Checking the lower bit (for bits ordering):
ffmpeg -y -lavfi color=0x000008:size=8x8:rate=1:duration=1 -pix_fmt rgb555be -f rawvideo red.raw
ffmpeg -y -lavfi color=0x000800:size=8x8:rate=1:duration=1 -pix_fmt rgb555be -f rawvideo green.raw
ffmpeg -y -lavfi color=0x080000:size=8x8:rate=1:duration=1 -pix_fmt rgb555be -f rawvideo blue.raw
r: 00 01 00 01
g: 00 20 00 20
b: 04 00 04 00
In big endian format, only the bytes are swapped.
(For every uint16 element (two bytes), order of the first and second byte is swapped).
Answers to questions:
- Do we read the R component as
10000=16 or 00001=1 ?
Answer:
For rgb555le: 00000001 00000000
For rgb555be: 00000000 00000001
- I'm even more confused about if the way we read the component (bit endianness) is related to byte endianness?
Answer:
In context of pixel format, there is no "bit endianness" there is only "byte endianness".
Bits endianness is more relevant to serial communication, from software perspective, we don't see the order of bits in each byte.
- Which way is RGB555LE format represented in byte array?
Answer:
RGB555LE (as RGB555LE_v1):
byte0 byte1
gggbbbbb 0rrrrrgg
(most left bit is the upper bit in each byte).
We better look at the data as one uint16 element:
b: 0000000000011111 (pure blue)
g: 0000001111100000 (pure green)
r: 0111110000000000 (pure red)
We may look at it as uint16 as: 0rrrrrgggggbbbbb