Display Data Format
Shared by both OpenDisplay Basic and OpenDisplay Flex standards
Overview
This page explains how image data is encoded into bytes for transmission to OpenDisplay devices. The encoding format depends on the color scheme configured for the display. Understanding this format is essential for implementing custom clients or debugging image transfer issues.
The image encoding format is identical for both OpenDisplay Basic and OpenDisplay Flex standards. However, the transmission protocols differ:
- Basic: Image data is sent in the "New Image" response packet (0x82) as part of the simple request-response protocol
- Flex: Image data is sent using the Direct Write protocol (commands 0x0070, 0x0071, 0x0072) with chunking and compression support
Color Scheme 0: Monochrome (B/W)
Encoding: 1 bit per pixel, 8 pixels per byte
Colors: Black (0) or White (1)
Data Size: (width × height) ÷ 8 bytes
How It Works
Each pixel is represented by a single bit. White pixels set the bit to 1, black pixels set it to 0. Bits are packed into bytes from left to right, with the most significant bit (MSB) representing the leftmost pixel.
Example: 8 pixels in a row
Color Scheme 1: B/W + Red
Encoding: Bitplanes, 1 bit per pixel per plane, 8 pixels per byte per plane
Colors: Black, White, Red
Data Size: ((width × height) ÷ 8) × 2 bytes (two planes)
How It Works
This scheme uses two bitplanes (planes). Plane 1 encodes black/white information, and Plane 2 encodes red information. The final color is determined by combining both planes:
- Black: Plane 1 = 0, Plane 2 = 0
- White: Plane 1 = 1, Plane 2 = 0
- Red: Plane 1 = 1, Plane 2 = 1
Data is sent as: All Plane 1 bytes, then all Plane 2 bytes
Example: 8 pixels in a row
Final Data: 0xB6, 0x24 (Plane 1 first, then Plane 2)
Color Scheme 2: B/W + Yellow
Encoding: Bitplanes, 1 bit per pixel per plane, 8 pixels per byte per plane
Colors: Black, White, Yellow
Data Size: ((width × height) ÷ 8) × 2 bytes (two planes)
How It Works
Similar to Scheme 1, but Plane 2 encodes yellow instead of red:
- Black: Plane 1 = 0, Plane 2 = 0
- White: Plane 1 = 1, Plane 2 = 0
- Yellow: Plane 1 = 0, Plane 2 = 1
Data is sent as: All Plane 1 bytes, then all Plane 2 bytes
Color Scheme 3: B/W + Red + Yellow
Encoding: 2 bits per pixel, 4 pixels per byte
Colors: Black (0), White (1), Yellow (2), Red (3)
Data Size: (width × height) ÷ 4 bytes
How It Works
Each pixel uses 2 bits to encode one of four colors. Pixels are packed left to right, with the leftmost pixel using bits 7-6, next pixel using bits 5-4, and so on.
Example: 4 pixels in a row
Bit pairs (left to right): 01 (White), 00 (Black), 10 (Yellow), 11 (Red)
Color Scheme 4: 6-Color (B/W + Green + Blue + Red + Yellow)
Encoding: 4 bits per pixel, 2 pixels per byte
Colors: Black (0), White (1), Yellow (2), Red (3), Blue (5), Green (6)
Data Size: (width × height) ÷ 2 bytes
How It Works
Each pixel uses 4 bits (a nibble) to encode one of six colors. Two pixels fit in each byte, with the leftmost pixel in the upper nibble (bits 7-4) and the rightmost pixel in the lower nibble (bits 3-0).
Color Values
0
1
2
3
5
6
Visual Examples
Example 1: Black + White
Example 2: White + Red
Example 3: Yellow + Blue
Example 4: Red + Green
Example 5: All Colors (6 pixels)
Complete Data: 0x01, 0x23, 0x56
Color Scheme 5: 4 Grayscale
Encoding: 2 bits per pixel, 4 pixels per byte
Colors: Black (0), Dark Gray (1), Light Gray (2), White (3)
Data Size: (width × height) ÷ 4 bytes
How It Works
Each pixel uses 2 bits to encode one of four grayscale levels. Pixels are packed left to right, similar to Scheme 3, with the leftmost pixel using bits 7-6, next pixel using bits 5-4, and so on.
Example: 4 pixels in a row
Bit pairs (left to right): 11 (White), 00 (Black), 10 (Light Gray), 01 (Dark Gray)
Pixel Ordering
Pixels are always processed in row-major order: from top to bottom, left to right within each row.
Example: 4×4 Image
Order: 0 → 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10 → 11 → 12 → 13 → 14 → 15
Byte Packing for Scheme 0 (1 bit/pixel)
Row 0: Pixel 0, Pixel 1, Pixel 2, Pixel 3
Row 1: Pixel 4, Pixel 5, Pixel 6, Pixel 7
Row 2: Pixel 8, Pixel 9, Pixel 10, Pixel 11
Row 3: Pixel 12, Pixel 13, Pixel 14, Pixel 15
Byte 0: Pixels 0-7 (Row 0: 0-3, Row 1: 4-7)
Byte 1: Pixels 8-15 (Row 2: 8-11, Row 3: 12-15)
For bitplane schemes (1 and 2), all rows of Plane 1 are sent first, then all rows of Plane 2.
Implementation Notes
- When a row doesn't fill a complete byte, the remaining bits in the last byte are padded with zeros.
- For bitplane schemes, ensure Plane 1 and Plane 2 have the same number of bytes.
- Color detection from RGB values uses thresholds: pixels are classified based on their RGB components.
- The image data must be sent in the rotated orientation. The client should apply rotation before encoding the pixel data.
- Data can be compressed using zlib before transmission to reduce transfer size.
- Image data is written directly to the framebuffer, so there is no size limit for uncompressed images. Only compressed data is limited by the compression buffer size (50 KB).
Transmission Protocols
While the image encoding format is identical for both standards, the transmission protocols differ. This section explains how image data is sent in each standard.
OpenDisplay Basic
In the Basic standard, image data is sent as part of the "New Image" response packet (0x82):
Packet Type: 0x82
Offset 0: packet_type (1 byte) = 0x82
Offset 1-2: image_length (2 bytes, uint16, little-endian)
Offset 3 to (3+image_length-1): image_data (variable)
Offset (3+image_length) to (6+image_length): poll_interval (4 bytes, uint32, little-endian)
- Image Data: Raw encoded pixel data (or compressed using zlib)
- No Chunking: Entire image is sent in one packet (wrapped in outer packet format for TCP)
- TCP Support: Over TCP, packets can be up to 8KB, allowing larger images in a single transmission
- BLE Support: Over BLE, the image data must fit within BLE packet size limits (~200 bytes per chunk)
See OpenDisplay Basic for complete packet specifications.
OpenDisplay Flex
In the Flex standard, image data is sent using the Direct Write protocol with chunking and compression support:
Start Command (0x0070)
Command: 0x00 0x70
Payload (uncompressed):
- Width: 2 bytes (little-endian)
- Height: 2 bytes (little-endian)
- Color scheme: 1 byte
- Refresh mode: 1 byte
Payload (compressed):
- Uncompressed size: 4 bytes (little-endian)
- Compressed data: variable (up to 200 bytes in start command for BLE, up to 1000 bytes for TCP)
Data Command (0x0071)
Command: 0x00 0x71
Payload: Image data chunk
- BLE: up to 230 bytes per chunk
- TCP: up to 1000 bytes per chunk
End Command (0x0072)
Command: 0x00 0x72
Payload: Refresh mode flag (1 byte, optional)
- 0x00: Full refresh (default)
- 0x01: Fast/partial refresh
Maximum Packet Sizes
| Transport | Standard | Maximum Chunk Size |
|---|---|---|
| BLE | Basic | ~200 bytes (wrapped in outer packet) |
| BLE | Flex | 230 bytes per chunk (0x0071 command) |
| TCP | Basic | Up to 8KB (wrapped in outer packet) |
| TCP | Flex | 1000 bytes per chunk (0x0071 command) |
Compression
Both standards support zlib compression of image data:
- Basic: Compressed data is included directly in the image_data field of packet 0x82
- Flex: Compressed data is sent in the Direct Write protocol, with uncompressed size in the start command (0x0070)
- Compressed Data Buffer Limit: 50 KB (50,000 bytes) - if compressed data exceeds this, use uncompressed mode
- Uncompressed Image Size: No limit - image data is written directly to the framebuffer, so uncompressed images can be any size that fits in device memory
See OpenDisplay Flex and BLE Communication Protocol for complete protocol specifications.