Skip to content

Commit d012561

Browse files
authored
Merge pull request #4428 from kmatch98/bitmap-read-2
Add `reverse_rows` to speedy bitmaptools.readinto function
2 parents 623ece2 + c37a1f4 commit d012561

File tree

4 files changed

+28
-22
lines changed

4 files changed

+28
-22
lines changed

locale/circuitpython.pot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,7 @@ msgstr ""
550550
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
551551
#: ports/esp32s2/common-hal/displayio/ParallelBus.c
552552
#: ports/nrf/common-hal/displayio/ParallelBus.c
553+
#: ports/raspberrypi/common-hal/displayio/ParallelBus.c
553554
#, c-format
554555
msgid "Bus pin %d is already in use"
555556
msgstr ""
@@ -1729,7 +1730,6 @@ msgid "PWM slice channel A already in use"
17291730
msgstr ""
17301731

17311732
#: ports/mimxrt10xx/common-hal/displayio/ParallelBus.c
1732-
#: ports/raspberrypi/common-hal/displayio/ParallelBus.c
17331733
#: ports/stm/common-hal/displayio/ParallelBus.c
17341734
msgid "ParallelBus not yet supported"
17351735
msgstr ""

shared-bindings/bitmaptools/__init__.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -361,20 +361,20 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_line_obj, 0, bitmaptools_obj_draw_li
361361
//| def arrayblit(bitmap: displayio.Bitmap, data: ReadableBuffer, x1: int=0, y1: int=0, x2: Optional[int]=None, y2: Optional[int]=None, skip_index:Optional[int]=None) -> None:
362362
//| """Inserts pixels from ``data`` into the rectangle of width×height pixels with the upper left corner at ``(x,y)``
363363
//|
364-
//| The values from ``data`` are taken modulo the number of color values
365-
//| avalable in the destination bitmap.
364+
//| The values from ``data`` are taken modulo the number of color values
365+
//| avalable in the destination bitmap.
366366
//|
367-
//| If x1 or y1 are not specified, they are taken as 0. If x2 or y2
368-
//| are not specified, or are given as -1, they are taken as the width
369-
//| and height of the image.
367+
//| If x1 or y1 are not specified, they are taken as 0. If x2 or y2
368+
//| are not specified, or are given as -1, they are taken as the width
369+
//| and height of the image.
370370
//|
371-
//| The coordinates affected by the blit are ``x1 <= x < x2`` and ``y1 <= y < y2``.
371+
//| The coordinates affected by the blit are ``x1 <= x < x2`` and ``y1 <= y < y2``.
372372
//|
373-
//| ``data`` must contain at least as many elements as required. If it
374-
//| contains excess elements, they are ignored.
373+
//| ``data`` must contain at least as many elements as required. If it
374+
//| contains excess elements, they are ignored.
375375
//|
376-
//| The blit takes place by rows, so the first elements of ``data`` go
377-
//| to the first row, the next elements to the next row, and so on.
376+
//| The blit takes place by rows, so the first elements of ``data`` go
377+
//| to the first row, the next elements to the next row, and so on.
378378
//|
379379
//| :param displayio.Bitmap bitmap: A writable bitmap
380380
//| :param ReadableBuffer data: Buffer containing the source pixel values
@@ -436,33 +436,37 @@ STATIC mp_obj_t bitmaptools_arrayblit(size_t n_args, const mp_obj_t *pos_args, m
436436
MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_arrayblit_obj, 0, bitmaptools_arrayblit);
437437

438438

439-
//| def readinto(bitmap: displayio.Bitmap, file: typing.BinaryIO, bits_per_pixel: int, element_size: int = 1, reverse_pixels_in_element: bool = False, swap_bytes_in_element: bool = False) -> None:
440-
//| """Read from a binary file into a bitmap
441-
//| The file must be positioned so that it consists of ``bitmap.height`` rows of pixel data, where each row is the smallest multiple of ``element_size`` bytes that can hold ``bitmap.width`` pixels.
439+
//| def readinto(bitmap: displayio.Bitmap, file: typing.BinaryIO, bits_per_pixel: int, element_size: int = 1, reverse_pixels_in_element: bool = False, swap_bytes_in_element: bool = False, reverse_rows: bool = False) -> None:
440+
//| """Reads from a binary file into a bitmap.
442441
//|
443-
//| The bytes in an element can be optionally swapped, and the pixels in an element can be reversed.
442+
//| The file must be positioned so that it consists of ``bitmap.height`` rows of pixel data, where each row is the smallest multiple of ``element_size`` bytes that can hold ``bitmap.width`` pixels.
444443
//|
445-
//| This function doesn't parse image headers, but is useful to speed up loading of uncompressed image formats such as PCF glyph data.
444+
//| The bytes in an element can be optionally swapped, and the pixels in an element can be reversed. Also, the
445+
//| row loading direction can be reversed, which may be requires for loading certain bitmap files.
446+
//|
447+
//| This function doesn't parse image headers, but is useful to speed up loading of uncompressed image formats such as PCF glyph data.
446448
//|
447449
//| :param displayio.Bitmap bitmap: A writable bitmap
448450
//| :param typing.BinaryIO file: A file opened in binary mode
449451
//| :param int bits_per_pixel: Number of bits per pixel. Values 1, 2, 4, 8, 16, 24, and 32 are supported;
450452
//| :param int element_size: Number of bytes per element. Values of 1, 2, and 4 are supported, except that 24 ``bits_per_pixel`` requires 1 byte per element.
451453
//| :param bool reverse_pixels_in_element: If set, the first pixel in a word is taken from the Most Signficant Bits; otherwise, it is taken from the Least Significant Bits.
452454
//| :param bool swap_bytes_in_element: If the ``element_size`` is not 1, then reverse the byte order of each element read.
455+
//| :param bool reverse_rows: Reverse the direction of the row loading (required for some bitmap images).
453456
//| """
454457
//| ...
455458
//|
456459

457460
STATIC mp_obj_t bitmaptools_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
458-
enum { ARG_bitmap, ARG_file, ARG_bits_per_pixel, ARG_element_size, ARG_reverse_pixels_in_element, ARG_swap_bytes_in_element };
461+
enum { ARG_bitmap, ARG_file, ARG_bits_per_pixel, ARG_element_size, ARG_reverse_pixels_in_element, ARG_swap_bytes_in_element, ARG_reverse_rows };
459462
static const mp_arg_t allowed_args[] = {
460463
{ MP_QSTR_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ },
461464
{ MP_QSTR_file, MP_ARG_REQUIRED | MP_ARG_OBJ },
462465
{ MP_QSTR_bits_per_pixel, MP_ARG_REQUIRED | MP_ARG_INT },
463466
{ MP_QSTR_element_size, MP_ARG_INT, { .u_int = 1 } },
464467
{ MP_QSTR_reverse_pixels_in_element, MP_ARG_BOOL, { .u_bool = false } },
465468
{ MP_QSTR_swap_bytes_in_element, MP_ARG_BOOL, { .u_bool = false } },
469+
{ MP_QSTR_reverse_rows, MP_ARG_BOOL, { .u_bool = false } },
466470
};
467471

468472
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@@ -503,8 +507,9 @@ STATIC mp_obj_t bitmaptools_readinto(size_t n_args, const mp_obj_t *pos_args, mp
503507

504508
bool reverse_pixels_in_element = args[ARG_reverse_pixels_in_element].u_bool;
505509
bool swap_bytes_in_element = args[ARG_swap_bytes_in_element].u_bool;
510+
bool reverse_rows = args[ARG_reverse_rows].u_bool;
506511

507-
common_hal_bitmaptools_readinto(bitmap, file, element_size, bits_per_pixel, reverse_pixels_in_element, swap_bytes_in_element);
512+
common_hal_bitmaptools_readinto(bitmap, file, element_size, bits_per_pixel, reverse_pixels_in_element, swap_bytes_in_element, reverse_rows);
508513

509514
return mp_const_none;
510515
}

shared-bindings/bitmaptools/__init__.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void common_hal_bitmaptools_draw_line(displayio_bitmap_t *destination,
5151
int16_t x1, int16_t y1,
5252
uint32_t value);
5353

54-
void common_hal_bitmaptools_readinto(displayio_bitmap_t *self, pyb_file_obj_t *file, int element_size, int bits_per_pixel, bool reverse_pixels_in_word, bool swap_bytes);
54+
void common_hal_bitmaptools_readinto(displayio_bitmap_t *self, pyb_file_obj_t *file, int element_size, int bits_per_pixel, bool reverse_pixels_in_word, bool swap_bytes, bool reverse_rows);
5555
void common_hal_bitmaptools_arrayblit(displayio_bitmap_t *self, void *data, int element_size, int x1, int y1, int x2, int y2, bool skip_specified, uint32_t skip_index);
5656

5757
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BITMAPTOOLS__INIT__H

shared-module/bitmaptools/__init__.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ void common_hal_bitmaptools_arrayblit(displayio_bitmap_t *self, void *data, int
404404
displayio_bitmap_set_dirty_area(self, x1, y1, x2, y2);
405405
}
406406

407-
void common_hal_bitmaptools_readinto(displayio_bitmap_t *self, pyb_file_obj_t *file, int element_size, int bits_per_pixel, bool reverse_pixels_in_element, bool swap_bytes) {
407+
void common_hal_bitmaptools_readinto(displayio_bitmap_t *self, pyb_file_obj_t *file, int element_size, int bits_per_pixel, bool reverse_pixels_in_element, bool swap_bytes, bool reverse_rows) {
408408
uint32_t mask = (1 << common_hal_displayio_bitmap_get_bits_per_value(self)) - 1;
409409

410410
if (self->read_only) {
@@ -415,10 +415,12 @@ void common_hal_bitmaptools_readinto(displayio_bitmap_t *self, pyb_file_obj_t *f
415415
size_t rowsize = element_size * elements_per_row;
416416
size_t rowsize_in_u32 = (rowsize + sizeof(uint32_t) - 1) / sizeof(uint32_t);
417417
size_t rowsize_in_u16 = (rowsize + sizeof(uint16_t) - 1) / sizeof(uint16_t);
418+
418419
for (int y = 0; y < self->height; y++) {
419420
uint32_t rowdata32[rowsize_in_u32];
420421
uint16_t *rowdata16 = (uint16_t *)rowdata32;
421422
uint8_t *rowdata8 = (uint8_t *)rowdata32;
423+
const int y_draw = reverse_rows ? (self->height) - 1 - y : y;
422424

423425
UINT bytes_read = 0;
424426
if (f_read(&file->fp, rowdata32, rowsize, &bytes_read) != FR_OK || bytes_read != rowsize) {
@@ -481,8 +483,7 @@ void common_hal_bitmaptools_readinto(displayio_bitmap_t *self, pyb_file_obj_t *f
481483
value = rowdata32[x];
482484
break;
483485
}
484-
485-
displayio_bitmap_write_pixel(self, x, y, value & mask);
486+
displayio_bitmap_write_pixel(self, x, y_draw, value & mask);
486487
}
487488
}
488489

0 commit comments

Comments
 (0)