33
33
void common_hal_displayio_bitmap_construct (displayio_bitmap_t * self , uint32_t width ,
34
34
uint32_t height , uint32_t bits_per_value ) {
35
35
uint32_t row_width = width * bits_per_value ;
36
- // word align
37
- if (row_width % 32 != 0 ) {
38
- self -> stride = (row_width / 32 + 1 );
36
+ // align to size_t
37
+ uint8_t align_bits = 8 * sizeof (size_t );
38
+ if (row_width % align_bits != 0 ) {
39
+ self -> stride = (row_width / align_bits + 1 );
39
40
} else {
40
- self -> stride = row_width / 32 ;
41
+ self -> stride = row_width / align_bits ;
41
42
}
42
43
self -> width = width ;
43
44
self -> height = height ;
44
- self -> data = m_malloc (self -> stride * height * sizeof (uint32_t ), false);
45
+ self -> data = m_malloc (self -> stride * height * sizeof (size_t ), false);
45
46
self -> read_only = false;
46
47
self -> bits_per_value = bits_per_value ;
47
48
48
- if (bits_per_value > 8 ) {
49
- mp_raise_NotImplementedError (translate ("Only bit maps of 8 bit color or less are supported " ));
49
+ if (bits_per_value > 8 && bits_per_value != 16 && bits_per_value != 32 ) {
50
+ mp_raise_NotImplementedError (translate ("Invalid bits per value " ));
50
51
}
51
52
52
53
// Division and modulus can be slow because it has to handle any integer. We know bits_per_value
@@ -56,7 +57,7 @@ void common_hal_displayio_bitmap_construct(displayio_bitmap_t *self, uint32_t wi
56
57
self -> x_shift = 0 ; // Used to divide the index by the number of pixels per word. Its used in a
57
58
// shift which effectively divides by 2 ** x_shift.
58
59
uint32_t power_of_two = 1 ;
59
- while (power_of_two < 32 / bits_per_value ) {
60
+ while (power_of_two < align_bits / bits_per_value ) {
60
61
self -> x_shift ++ ;
61
62
power_of_two <<= 1 ;
62
63
}
@@ -76,57 +77,50 @@ uint32_t common_hal_displayio_bitmap_get_bits_per_value(displayio_bitmap_t *self
76
77
return self -> bits_per_value ;
77
78
}
78
79
79
- void common_hal_displayio_bitmap_load_row (displayio_bitmap_t * self , uint16_t y , uint8_t * data , uint16_t len ) {
80
- if (len != self -> stride * sizeof (uint32_t )) {
81
- mp_raise_ValueError (translate ("row must be packed and word aligned" ));
82
- }
83
- uint32_t * row_value = self -> data + (y * self -> stride );
84
- // Do the memcpy ourselves since we may want to flip endianness.
85
- for (uint32_t i = 0 ; i < self -> stride ; i ++ ) {
86
- #pragma GCC diagnostic push
87
- #pragma GCC diagnostic ignored "-Wcast-align"
88
- uint32_t value = ((uint32_t * )data )[i ];
89
- #pragma GCC diagnostic pop
90
- if (self -> bits_per_value < 16 ) {
91
- value = ((value >> 24 ) & 0xff ) |
92
- ((value << 8 ) & 0xff0000 ) |
93
- ((value >> 8 ) & 0xff00 ) |
94
- ((value << 24 ) & 0xff000000 );
95
- }
96
- * row_value = value ;
97
- row_value ++ ;
98
- }
99
- }
100
-
101
80
uint32_t common_hal_displayio_bitmap_get_pixel (displayio_bitmap_t * self , int16_t x , int16_t y ) {
102
81
if (x >= self -> width || x < 0 || y >= self -> height || y < 0 ) {
103
82
return 0 ;
104
83
}
105
84
int32_t row_start = y * self -> stride ;
106
- if (self -> bits_per_value < 8 ) {
107
- uint32_t word = self -> data [row_start + (x >> self -> x_shift )];
85
+ uint32_t bytes_per_value = self -> bits_per_value / 8 ;
86
+ if (bytes_per_value < 1 ) {
87
+ size_t word = self -> data [row_start + (x >> self -> x_shift )];
108
88
109
- return (word >> (32 - ((x & self -> x_mask ) + 1 ) * self -> bits_per_value )) & self -> bitmask ;
89
+ return (word >> (sizeof ( size_t ) * 8 - ((x & self -> x_mask ) + 1 ) * self -> bits_per_value )) & self -> bitmask ;
110
90
} else {
111
- uint32_t bytes_per_value = self -> bits_per_value / 8 ;
112
- return self -> data [row_start + x * bytes_per_value ];
91
+ size_t * row = self -> data + row_start ;
92
+ if (bytes_per_value == 1 ) {
93
+ return ((uint8_t * ) row )[x ];
94
+ } else if (bytes_per_value == 2 ) {
95
+ return ((uint16_t * ) row )[x ];
96
+ } else if (bytes_per_value == 4 ) {
97
+ return ((uint32_t * ) row )[x ];
98
+ }
113
99
}
100
+ return 0 ;
114
101
}
115
102
116
103
void common_hal_displayio_bitmap_set_pixel (displayio_bitmap_t * self , int16_t x , int16_t y , uint32_t value ) {
117
104
if (self -> read_only ) {
118
105
mp_raise_RuntimeError (translate ("Read-only object" ));
119
106
}
120
107
int32_t row_start = y * self -> stride ;
121
- if (self -> bits_per_value < 8 ) {
122
- uint32_t bit_position = (32 - ((x & self -> x_mask ) + 1 ) * self -> bits_per_value );
108
+ uint32_t bytes_per_value = self -> bits_per_value / 8 ;
109
+ if (bytes_per_value < 1 ) {
110
+ uint32_t bit_position = (sizeof (size_t ) * 8 - ((x & self -> x_mask ) + 1 ) * self -> bits_per_value );
123
111
uint32_t index = row_start + (x >> self -> x_shift );
124
112
uint32_t word = self -> data [index ];
125
113
word &= ~(self -> bitmask << bit_position );
126
114
word |= (value & self -> bitmask ) << bit_position ;
127
115
self -> data [index ] = word ;
128
116
} else {
129
- uint32_t bytes_per_value = self -> bits_per_value / 8 ;
130
- self -> data [row_start + x * bytes_per_value ] = value ;
117
+ size_t * row = self -> data + row_start ;
118
+ if (bytes_per_value == 1 ) {
119
+ ((uint8_t * ) row )[x ] = value ;
120
+ } else if (bytes_per_value == 2 ) {
121
+ ((uint16_t * ) row )[x ] = value ;
122
+ } else if (bytes_per_value == 4 ) {
123
+ ((uint32_t * ) row )[x ] = value ;
124
+ }
131
125
}
132
126
}
0 commit comments