16
16
import sys
17
17
18
18
try :
19
- from typing import Tuple , Optional
19
+ from typing import Union , Optional , Tuple
20
20
from io import BufferedReader
21
- from displayio import Bitmap
22
21
from ..displayio_types import BitmapConstructor
23
22
except ImportError :
24
23
pass
25
24
26
- from displayio import ColorConverter , Colorspace
25
+ from displayio import ColorConverter , Colorspace , Bitmap
27
26
28
27
__version__ = "0.0.0+auto.0"
29
28
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_ImageLoad.git"
30
29
30
+ bitfield_colorspaces = (
31
+ { # 16-bit RGB555
32
+ "mask_values" : (0x00007C00 , 0x000003E0 , 0x0000001F ),
33
+ "color_space" : Colorspace .RGB555 ,
34
+ },
35
+ { # 16-bit RGB565
36
+ "mask_values" : (0x0000F800 , 0x000007E0 , 0x0000001F ),
37
+ "color_space" : Colorspace .RGB565 ,
38
+ },
39
+ { # 24 or 32-bit RGB888 (Alpha ignored for 32-bit)
40
+ "mask_values" : (0x0000FF00 , 0x00FF0000 , 0xFF000000 ),
41
+ "color_space" : Colorspace .RGB888 ,
42
+ },
43
+ )
44
+
45
+
46
+ def bitfield_format (bitfield_mask ):
47
+ """Returns the colorspace for the given bitfield mask"""
48
+ mask = (bitfield_mask ["red" ], bitfield_mask ["green" ], bitfield_mask ["blue" ])
49
+ for colorspace in bitfield_colorspaces :
50
+ if colorspace ["mask_values" ] == mask :
51
+ return colorspace ["color_space" ]
52
+ return None
53
+
31
54
32
55
def load (
33
56
file : BufferedReader ,
34
57
width : int ,
35
58
height : int ,
36
59
data_start : int ,
37
60
color_depth : int ,
61
+ bitfield_masks : Union [dict , None ],
38
62
* ,
39
63
bitmap : Optional [BitmapConstructor ] = None ,
40
64
) -> Tuple [Optional [Bitmap ], Optional [ColorConverter ]]:
@@ -46,6 +70,7 @@ def load(
46
70
:param int height: Image height in pixels
47
71
:param int data_start: Byte location where the data starts (after headers)
48
72
:param int color_depth: Number of bits used to store a value
73
+ :param dict bitfield_masks: The bitfield masks for each color if using bitfield compression
49
74
:param BitmapConstructor bitmap: a function that returns a displayio.Bitmap
50
75
"""
51
76
# pylint: disable=too-many-arguments,too-many-locals,too-many-branches
@@ -55,7 +80,13 @@ def load(
55
80
# Set up a ColorConverter object and set appropriate colorspace
56
81
# to convert from based on the color depth
57
82
input_colorspace = Colorspace .RGB888
58
- if color_depth == 16 :
83
+ if bitfield_masks is not None :
84
+ colorspace = bitfield_format (bitfield_masks )
85
+ if colorspace is not None :
86
+ input_colorspace = colorspace
87
+ else :
88
+ raise NotImplementedError ("Bitfield mask not supported" )
89
+ elif color_depth == 16 :
59
90
input_colorspace = Colorspace .RGB555
60
91
converter_obj = ColorConverter (input_colorspace = input_colorspace )
61
92
if sys .maxsize > 1073741823 :
@@ -64,7 +95,7 @@ def load(
64
95
65
96
# convert unsigned int to signed int when height is negative
66
97
height = negative_height_check (height )
67
- bitmap_obj = bitmap (width , abs (height ), 65535 )
98
+ bitmap_obj = Bitmap (width , abs (height ), 65535 )
68
99
file .seek (data_start )
69
100
line_size = width * (color_depth // 8 )
70
101
# Set the seek direction based on whether the height value is negative or positive
@@ -84,10 +115,23 @@ def load(
84
115
85
116
for x in range (width ):
86
117
i = x * bytes_per_pixel
87
- if color_depth == 16 :
88
- pixel = chunk [i ] | chunk [i + 1 ] << 8
118
+ if bitfield_masks is not None :
119
+ color = 0
120
+ for byte in range (bytes_per_pixel ):
121
+ color |= chunk [i + byte ] << (8 * byte )
122
+ mask = (
123
+ bitfield_masks ["red" ]
124
+ | bitfield_masks ["green" ]
125
+ | bitfield_masks ["blue" ]
126
+ )
127
+ if color_depth in (24 , 32 ):
128
+ mask = mask >> 8
129
+ pixel = color & mask
89
130
else :
90
- pixel = chunk [i + 2 ] << 16 | chunk [i + 1 ] << 8 | chunk [i ]
131
+ if color_depth == 16 :
132
+ pixel = chunk [i ] | chunk [i + 1 ] << 8
133
+ else :
134
+ pixel = chunk [i + 2 ] << 16 | chunk [i + 1 ] << 8 | chunk [i ]
91
135
bitmap_obj [offset + x ] = converter_obj .convert (pixel )
92
136
93
137
return bitmap_obj , ColorConverter (input_colorspace = Colorspace .RGB565 )
0 commit comments