2020-08-19 15:59:51 +00:00
|
|
|
# Trezor Optimized Image Format (TOIF)
|
2016-04-25 18:01:16 +00:00
|
|
|
|
2016-04-27 16:45:00 +00:00
|
|
|
All multibyte integer values are little endian!
|
2016-04-25 20:02:12 +00:00
|
|
|
|
2017-03-20 14:49:11 +00:00
|
|
|
## Header
|
2016-04-25 18:01:16 +00:00
|
|
|
|
|
|
|
| offset | length | name | description |
|
|
|
|
|-------:|-------:|------|-------------|
|
|
|
|
| 0x0000 | 3 | magic | `TOI` |
|
|
|
|
| 0x0003 | 1 | fmt | data format: `f` or `g` (see below) |
|
2016-04-25 20:02:12 +00:00
|
|
|
| 0x0004 | 2 | width | width of the image |
|
|
|
|
| 0x0006 | 2 | height | height of the image |
|
|
|
|
| 0x0008 | 4 | datasize | length of the compressed data |
|
2016-04-25 18:01:16 +00:00
|
|
|
| 0x000A | ? | data | compressed data (see below) |
|
|
|
|
|
2017-03-20 14:49:11 +00:00
|
|
|
## Format
|
2016-04-25 18:01:16 +00:00
|
|
|
|
2022-08-16 14:51:10 +00:00
|
|
|
TOI currently supports 4 variants:
|
2016-04-25 18:01:16 +00:00
|
|
|
|
2022-08-16 14:51:10 +00:00
|
|
|
* `f`: full-color big endian
|
|
|
|
* `F`: full-color little endian
|
|
|
|
* `g`: gray-scale odd high
|
|
|
|
* `G`: gray-scale even high
|
2016-04-25 18:01:16 +00:00
|
|
|
|
2017-03-20 14:49:11 +00:00
|
|
|
### Full-color
|
2016-04-25 18:01:16 +00:00
|
|
|
|
2017-04-12 12:45:58 +00:00
|
|
|
For each pixel a 16-bit value is used.
|
|
|
|
First 5 bits are used for red component, next 6 bits are green,
|
|
|
|
final 5 bits are blue:
|
2016-04-25 18:01:16 +00:00
|
|
|
|
|
|
|
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
|
|
|----|----|----|----|----|----|---|---|---|---|---|---|---|---|---|---|
|
|
|
|
| R | R | R | R | R | G | G | G | G | G | G | B | B | B | B | B |
|
|
|
|
|
2022-08-16 14:51:10 +00:00
|
|
|
The data is stored according to endianness.
|
|
|
|
|
2017-03-20 14:49:11 +00:00
|
|
|
### Gray-scale
|
2016-04-25 18:01:16 +00:00
|
|
|
|
2017-04-12 12:45:58 +00:00
|
|
|
Each pixel is encoded using a 4-bit value.
|
|
|
|
Each byte contains color of two pixels:
|
2016-04-25 18:01:16 +00:00
|
|
|
|
2022-08-16 14:51:10 +00:00
|
|
|
#### Odd high:
|
|
|
|
|
2016-04-25 18:01:16 +00:00
|
|
|
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
|
|
|---|---|---|---|---|---|---|---|
|
|
|
|
| Po | Po | Po | Po | Pe | Pe | Pe | Pe |
|
|
|
|
|
2022-08-16 14:51:10 +00:00
|
|
|
#### Even high:
|
|
|
|
|
|
|
|
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
|
|
|-----|-----|-----|-----|-----|-----|-----|-----|
|
|
|
|
| Pe | Pe | Pe | Pe | Po | Po | Po | Po |
|
|
|
|
|
2016-04-25 18:01:16 +00:00
|
|
|
Where Po is odd pixel and Pe is even pixel.
|
|
|
|
|
2017-03-20 14:49:11 +00:00
|
|
|
## Compression
|
2016-04-25 18:01:16 +00:00
|
|
|
|
2017-04-12 12:45:58 +00:00
|
|
|
Pixel data is compressed using DEFLATE algorithm with 10-bit sliding window
|
|
|
|
and no header. This can be achieved with ZLIB library by using the following:
|
2016-04-25 18:01:16 +00:00
|
|
|
|
2017-03-20 14:49:11 +00:00
|
|
|
```python
|
2016-04-25 18:01:16 +00:00
|
|
|
import zlib
|
2019-11-28 13:00:29 +00:00
|
|
|
z = zlib.compressobj(level=9, wbits=-10)
|
2016-04-25 18:01:16 +00:00
|
|
|
zdata = z.compress(pixeldata) + z.flush()
|
|
|
|
```
|
|
|
|
|
2017-03-20 14:49:11 +00:00
|
|
|
## Tools
|
2016-04-25 18:01:16 +00:00
|
|
|
|
2020-12-14 15:18:38 +00:00
|
|
|
* [toif_convert](https://github.com/trezor/trezor-firmware/blob/master/core/tools/toif_convert.py) - tool for converting PNGs into TOI format and back
|