@@ -169,7 +169,8 @@ void _pixelbuf_parse_color(pixelbuf_pixelbuf_obj_t* self, mp_obj_t color, uint8_
169
169
mp_obj_t * items ;
170
170
size_t len ;
171
171
mp_obj_get_array (color , & len , & items );
172
- if (len != byteorder -> bpp && !byteorder -> is_dotstar ) {
172
+ size_t n_elems = self -> byteorder .bpp == 2 ? 3 : self -> byteorder .bpp ;
173
+ if (len != n_elems && !byteorder -> is_dotstar ) {
173
174
mp_raise_ValueError_varg (translate ("Expected tuple of length %d, got %d" ), byteorder -> bpp , len );
174
175
}
175
176
@@ -187,8 +188,6 @@ void _pixelbuf_parse_color(pixelbuf_pixelbuf_obj_t* self, mp_obj_t color, uint8_
187
188
}
188
189
189
190
void _pixelbuf_set_pixel_color (pixelbuf_pixelbuf_obj_t * self , size_t index , uint8_t r , uint8_t g , uint8_t b , uint8_t w ) {
190
- // DotStars don't have white, instead they have 5 bit brightness so pack it into w. Shift right
191
- // by three to leave the top five bits.
192
191
if (self -> bytes_per_pixel == 4 && self -> byteorder .is_dotstar ) {
193
192
w = DOTSTAR_LED_START | w >> 3 ;
194
193
}
@@ -200,9 +199,15 @@ void _pixelbuf_set_pixel_color(pixelbuf_pixelbuf_obj_t* self, size_t index, uint
200
199
pre_brightness_buffer [rgbw_order -> w ] = w ;
201
200
}
202
201
203
- pre_brightness_buffer [rgbw_order -> r ] = r ;
204
- pre_brightness_buffer [rgbw_order -> g ] = g ;
205
- pre_brightness_buffer [rgbw_order -> b ] = b ;
202
+ if (self -> bytes_per_pixel == 2 ) {
203
+ uint16_t rgb565 = ((r << 8 ) & 0xf800 ) | ((g <<3 ) & 0xfc0 ) | (b >> 3 );
204
+ pre_brightness_buffer [0 ] = rgb565 & 0xff ;
205
+ pre_brightness_buffer [1 ] = rgb565 >> 8 ;
206
+ } else {
207
+ pre_brightness_buffer [rgbw_order -> r ] = r ;
208
+ pre_brightness_buffer [rgbw_order -> g ] = g ;
209
+ pre_brightness_buffer [rgbw_order -> b ] = b ;
210
+ }
206
211
}
207
212
208
213
uint8_t * post_brightness_buffer = self -> post_brightness_buffer + offset ;
@@ -213,9 +218,18 @@ void _pixelbuf_set_pixel_color(pixelbuf_pixelbuf_obj_t* self, size_t index, uint
213
218
}
214
219
post_brightness_buffer [rgbw_order -> w ] = w ;
215
220
}
216
- post_brightness_buffer [rgbw_order -> r ] = r * self -> brightness ;
217
- post_brightness_buffer [rgbw_order -> g ] = g * self -> brightness ;
218
- post_brightness_buffer [rgbw_order -> b ] = b * self -> brightness ;
221
+ if (self -> bytes_per_pixel == 2 ) {
222
+ r *= self -> brightness ;
223
+ g *= self -> brightness ;
224
+ b *= self -> brightness ;
225
+ uint16_t rgb565 = ((r << 8 ) & 0xf800 ) | ((g <<3 ) & 0x0fc0 ) | (b >> 3 );
226
+ post_brightness_buffer [0 ] = rgb565 & 0xff ;
227
+ post_brightness_buffer [1 ] = rgb565 >> 8 ;
228
+ } else {
229
+ post_brightness_buffer [rgbw_order -> r ] = r * self -> brightness ;
230
+ post_brightness_buffer [rgbw_order -> g ] = g * self -> brightness ;
231
+ post_brightness_buffer [rgbw_order -> b ] = b * self -> brightness ;
232
+ }
219
233
}
220
234
221
235
void _pixelbuf_set_pixel (pixelbuf_pixelbuf_obj_t * self , size_t index , mp_obj_t value ) {
@@ -249,27 +263,41 @@ void common_hal__pixelbuf_pixelbuf_set_pixel(mp_obj_t self_in, size_t index, mp_
249
263
250
264
mp_obj_t common_hal__pixelbuf_pixelbuf_get_pixel (mp_obj_t self_in , size_t index ) {
251
265
pixelbuf_pixelbuf_obj_t * self = native_pixelbuf (self_in );
252
- mp_obj_t elems [self -> byteorder .bpp ];
266
+ size_t n_elems = self -> byteorder .bpp == 2 ? 3 : self -> byteorder .bpp ;
267
+ mp_obj_t elems [n_elems ];
253
268
uint8_t * pixel_buffer = self -> post_brightness_buffer ;
254
269
if (self -> pre_brightness_buffer != NULL ) {
255
270
pixel_buffer = self -> pre_brightness_buffer ;
256
271
}
257
272
pixel_buffer += self -> byteorder .bpp * index ;
258
273
259
- pixelbuf_rgbw_t * rgbw_order = & self -> byteorder .byteorder ;
260
- elems [0 ] = MP_OBJ_NEW_SMALL_INT (pixel_buffer [rgbw_order -> r ]);
261
- elems [1 ] = MP_OBJ_NEW_SMALL_INT (pixel_buffer [rgbw_order -> g ]);
262
- elems [2 ] = MP_OBJ_NEW_SMALL_INT (pixel_buffer [rgbw_order -> b ]);
263
- if (self -> byteorder .bpp > 3 ) {
264
- uint8_t w = pixel_buffer [rgbw_order -> w ];
265
- if (self -> byteorder .is_dotstar ) {
266
- elems [3 ] = mp_obj_new_float ((w & 0b00011111 ) / 31.0 );
267
- } else {
268
- elems [3 ] = MP_OBJ_NEW_SMALL_INT (w );
274
+ if (self -> byteorder .bpp == 2 ) {
275
+ uint16_t rgb565 = pixel_buffer [0 ] + (pixel_buffer [1 ] << 8 );
276
+ uint8_t r = rgb565 >> 11 ;
277
+ uint8_t g = (rgb565 >> 5 ) & 0x3f ;
278
+ uint8_t b = rgb565 >> 5 & 0x1f ;
279
+ r |= r >> 3 ;
280
+ g |= g >> 2 ;
281
+ b |= b >> 3 ;
282
+ elems [0 ] = MP_OBJ_NEW_SMALL_INT (r );
283
+ elems [1 ] = MP_OBJ_NEW_SMALL_INT (g );
284
+ elems [2 ] = MP_OBJ_NEW_SMALL_INT (b );
285
+ } else {
286
+ pixelbuf_rgbw_t * rgbw_order = & self -> byteorder .byteorder ;
287
+ elems [0 ] = MP_OBJ_NEW_SMALL_INT (pixel_buffer [rgbw_order -> r ]);
288
+ elems [1 ] = MP_OBJ_NEW_SMALL_INT (pixel_buffer [rgbw_order -> g ]);
289
+ elems [2 ] = MP_OBJ_NEW_SMALL_INT (pixel_buffer [rgbw_order -> b ]);
290
+ if (self -> byteorder .bpp > 3 ) {
291
+ uint8_t w = pixel_buffer [rgbw_order -> w ];
292
+ if (self -> byteorder .is_dotstar ) {
293
+ elems [3 ] = mp_obj_new_float ((w & 0b00011111 ) / 31.0 );
294
+ } else {
295
+ elems [3 ] = MP_OBJ_NEW_SMALL_INT (w );
296
+ }
269
297
}
270
298
}
271
299
272
- return mp_obj_new_tuple (self -> byteorder . bpp , elems );
300
+ return mp_obj_new_tuple (n_elems , elems );
273
301
}
274
302
275
303
void common_hal__pixelbuf_pixelbuf_show (mp_obj_t self_in ) {
0 commit comments