@@ -28,6 +28,7 @@ static uint32_t read_word(uint16_t *bmp_header, uint16_t index) {
2828
2929void common_hal_displayio_ondiskbitmap_construct (displayio_ondiskbitmap_t * self , mp_obj_t file ) {
3030 self -> file = file ;
31+ self -> cache_len = 0 ;
3132 uint16_t bmp_header [69 ];
3233 int errcode = 0 ;
3334
@@ -182,43 +183,47 @@ uint32_t common_hal_displayio_ondiskbitmap_get_pixel(displayio_ondiskbitmap_t *s
182183 } else {
183184 location = self -> data_offset + (self -> height - y - 1 ) * self -> stride + x / pixels_per_byte ;
184185 }
185- // We don't cache here because the underlying FS caches sectors.
186186 int errcode = 0 ;
187- mp_stream_seek (self -> file , location , MP_SEEK_SET , & errcode );
188- if (errcode != 0 ) {
189- return 0 ;
187+ if (location < self -> cache_start || location + bytes_per_pixel > self -> cache_start + self -> cache_len ) {
188+ mp_stream_seek (self -> file , location , MP_SEEK_SET , & errcode );
189+ if (errcode != 0 ) {
190+ return 0 ;
191+ }
192+ self -> cache_start = location ;
193+ self -> cache_len = mp_stream_rw (self -> file , self -> cache , sizeof (self -> cache ), & errcode , MP_STREAM_RW_ONCE );
194+ if (errcode != 0 || self -> cache_len < bytes_per_pixel ) {
195+ self -> cache_len = 0 ;
196+ return 0 ;
197+ }
190198 }
191199 uint32_t pixel_data = 0 ;
192- mp_stream_rw (self -> file , & pixel_data , bytes_per_pixel , & errcode , MP_STREAM_RW_ONCE );
193- if (errcode == 0 ) {
194- uint32_t tmp = 0 ;
195- uint8_t red ;
196- uint8_t green ;
197- uint8_t blue ;
198- if (bytes_per_pixel == 1 ) {
199- uint8_t offset = (x % pixels_per_byte ) * self -> bits_per_pixel ;
200- uint8_t mask = (1 << self -> bits_per_pixel ) - 1 ;
201-
202- return (pixel_data >> ((8 - self -> bits_per_pixel ) - offset )) & mask ;
203- } else if (bytes_per_pixel == 2 ) {
204- if (self -> g_bitmask == 0x07e0 ) { // 565
205- red = ((pixel_data & self -> r_bitmask ) >> 11 );
206- green = ((pixel_data & self -> g_bitmask ) >> 5 );
207- blue = ((pixel_data & self -> b_bitmask ) >> 0 );
208- } else { // 555
209- red = ((pixel_data & self -> r_bitmask ) >> 10 );
210- green = ((pixel_data & self -> g_bitmask ) >> 4 );
211- blue = ((pixel_data & self -> b_bitmask ) >> 0 );
212- }
213- tmp = (red << 19 | green << 10 | blue << 3 );
214- return tmp ;
215- } else if ((bytes_per_pixel == 4 ) && (self -> bitfield_compressed )) {
216- return pixel_data & 0x00FFFFFF ;
217- } else {
218- return pixel_data ;
200+ memcpy (& pixel_data , self -> cache + (location - self -> cache_start ), bytes_per_pixel );
201+ uint32_t tmp = 0 ;
202+ uint8_t red ;
203+ uint8_t green ;
204+ uint8_t blue ;
205+ if (bytes_per_pixel == 1 ) {
206+ uint8_t offset = (x % pixels_per_byte ) * self -> bits_per_pixel ;
207+ uint8_t mask = (1 << self -> bits_per_pixel ) - 1 ;
208+
209+ return (pixel_data >> ((8 - self -> bits_per_pixel ) - offset )) & mask ;
210+ } else if (bytes_per_pixel == 2 ) {
211+ if (self -> g_bitmask == 0x07e0 ) { // 565
212+ red = ((pixel_data & self -> r_bitmask ) >> 11 );
213+ green = ((pixel_data & self -> g_bitmask ) >> 5 );
214+ blue = ((pixel_data & self -> b_bitmask ) >> 0 );
215+ } else { // 555
216+ red = ((pixel_data & self -> r_bitmask ) >> 10 );
217+ green = ((pixel_data & self -> g_bitmask ) >> 4 );
218+ blue = ((pixel_data & self -> b_bitmask ) >> 0 );
219219 }
220+ tmp = (red << 19 | green << 10 | blue << 3 );
221+ return tmp ;
222+ } else if ((bytes_per_pixel == 4 ) && (self -> bitfield_compressed )) {
223+ return pixel_data & 0x00FFFFFF ;
224+ } else {
225+ return pixel_data ;
220226 }
221- return 0 ;
222227}
223228
224229uint16_t common_hal_displayio_ondiskbitmap_get_height (displayio_ondiskbitmap_t * self ) {
0 commit comments