Skip to content

Commit c27d5ad

Browse files
committed
bitmaptools: Use standard coordinate range validators
**Potential incompatibility** these functions all validated their coordinates slightly differently. Now it is consistent.
1 parent 5dd689c commit c27d5ad

File tree

1 file changed

+22
-70
lines changed

1 file changed

+22
-70
lines changed

shared-bindings/bitmaptools/__init__.c

Lines changed: 22 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -450,14 +450,11 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_alphablend_obj, 0, bitmaptools_alphablend
450450
//| ...
451451
//|
452452
STATIC mp_obj_t bitmaptools_obj_fill_region(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
453-
enum {ARG_dest_bitmap, ARG_x1, ARG_y1, ARG_x2, ARG_y2, ARG_value};
453+
enum {ARG_dest_bitmap, ARGS_X1_Y1_X2_Y2, ARG_value};
454454

455455
static const mp_arg_t allowed_args[] = {
456456
{MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}},
457-
{MP_QSTR_x1, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}},
458-
{MP_QSTR_y1, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}},
459-
{MP_QSTR_x2, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}},
460-
{MP_QSTR_y2, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}},
457+
ALLOWED_ARGS_X1_Y1_X2_Y2(MP_ARG_REQUIRED, MP_ARG_REQUIRED),
461458
{MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}},
462459
};
463460
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@@ -472,12 +469,9 @@ STATIC mp_obj_t bitmaptools_obj_fill_region(size_t n_args, const mp_obj_t *pos_a
472469
mp_raise_ValueError(MP_ERROR_TEXT("out of range of target"));
473470
}
474471

475-
int16_t x1 = args[ARG_x1].u_int;
476-
int16_t y1 = args[ARG_y1].u_int;
477-
int16_t x2 = args[ARG_x2].u_int;
478-
int16_t y2 = args[ARG_y2].u_int;
472+
bitmaptools_rect_t lim = bitmaptools_validate_coord_range_pair(&args[ARG_x1], destination->width, destination->height);
479473

480-
common_hal_bitmaptools_fill_region(destination, x1, y1, x2, y2, value);
474+
common_hal_bitmaptools_fill_region(destination, lim.x1, lim.y1, lim.x2, lim.y2, value);
481475

482476
return mp_const_none;
483477
}
@@ -732,14 +726,11 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_polygon_obj, 0, bitmaptools_obj_draw
732726
//| ...
733727
//|
734728
STATIC mp_obj_t bitmaptools_arrayblit(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
735-
enum { ARG_bitmap, ARG_data, ARG_x1, ARG_y1, ARG_x2, ARG_y2, ARG_skip_index };
729+
enum { ARG_bitmap, ARG_data, ARGS_X1_Y1_X2_Y2, ARG_skip_index };
736730
static const mp_arg_t allowed_args[] = {
737731
{ MP_QSTR_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
738732
{ MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
739-
{ MP_QSTR_x1, MP_ARG_INT, {.u_int = 0} },
740-
{ MP_QSTR_y1, MP_ARG_INT, {.u_int = 0} },
741-
{ MP_QSTR_x2, MP_ARG_INT, {.u_int = -1} },
742-
{ MP_QSTR_y2, MP_ARG_INT, {.u_int = -1} },
733+
ALLOWED_ARGS_X1_Y1_X2_Y2(0, MP_ARG_REQUIRED),
743734
{ MP_QSTR_skip_index, MP_ARG_OBJ, {.u_obj = mp_const_none } },
744735
};
745736
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@@ -750,16 +741,9 @@ STATIC mp_obj_t bitmaptools_arrayblit(size_t n_args, const mp_obj_t *pos_args, m
750741
mp_buffer_info_t bufinfo;
751742
mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ);
752743

753-
int x1 = args[ARG_x1].u_int;
754-
int y1 = args[ARG_y1].u_int;
755-
int x2 = args[ARG_x2].u_int == -1 ? bitmap->width : args[ARG_x2].u_int;
756-
int y2 = args[ARG_y2].u_int == -1 ? bitmap->height : args[ARG_y2].u_int;
757-
758-
if ((x1 < 0) || (y1 < 0) || (x1 > x2) || (y1 > y2) || (x2 > bitmap->width) || (y2 > bitmap->height)) {
759-
mp_raise_IndexError(MP_ERROR_TEXT("pixel coordinates out of bounds"));
760-
}
744+
bitmaptools_rect_t lim = bitmaptools_validate_coord_range_pair(&args[ARG_x1], bitmap->width, bitmap->height);
761745

762-
size_t output_element_count = (x2 - x1) * (y2 - y1);
746+
size_t output_element_count = (lim.x2 - lim.x1) * (lim.y2 - lim.y1);
763747
size_t element_size = mp_binary_get_size('@', bufinfo.typecode, NULL);
764748
size_t input_element_count = bufinfo.len / element_size;
765749

@@ -769,7 +753,7 @@ STATIC mp_obj_t bitmaptools_arrayblit(size_t n_args, const mp_obj_t *pos_args, m
769753
mp_raise_IndexError(MP_ERROR_TEXT("index out of range"));
770754
}
771755

772-
common_hal_bitmaptools_arrayblit(bitmap, bufinfo.buf, element_size, x1, y1, x2, y2, skip_specified, skip_index);
756+
common_hal_bitmaptools_arrayblit(bitmap, bufinfo.buf, element_size, lim.x1, lim.y1, lim.x2, lim.y2, skip_specified, skip_index);
773757

774758
return mp_const_none;
775759
}
@@ -1031,12 +1015,12 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_circle_obj, 0, bitmaptools_obj_draw_
10311015
//| x: int,
10321016
//| y: int,
10331017
//| *,
1034-
//| x1: int,
1035-
//| y1: int,
1036-
//| x2: int,
1037-
//| y2: int,
1038-
//| skip_source_index: int,
1039-
//| skip_dest_index: int
1018+
//| x1: int = 0,
1019+
//| y1: int = 0,
1020+
//| x2: int | None = None,
1021+
//| y2: int | None = None,
1022+
//| skip_source_index: int | None = None,
1023+
//| skip_dest_index: int | None = None
10401024
//| ) -> None:
10411025
//| """Inserts the source_bitmap region defined by rectangular boundaries
10421026
//| (x1,y1) and (x2,y2) into the bitmap at the specified (x,y) location.
@@ -1049,8 +1033,8 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_circle_obj, 0, bitmaptools_obj_draw_
10491033
//| corner will be placed
10501034
//| :param int x1: Minimum x-value for rectangular bounding box to be copied from the source bitmap
10511035
//| :param int y1: Minimum y-value for rectangular bounding box to be copied from the source bitmap
1052-
//| :param int x2: Maximum x-value (exclusive) for rectangular bounding box to be copied from the source bitmap
1053-
//| :param int y2: Maximum y-value (exclusive) for rectangular bounding box to be copied from the source bitmap
1036+
//| :param int x2: Maximum x-value (exclusive) for rectangular bounding box to be copied from the source bitmap. If unspecified or `None`, the source bitmap width is used.
1037+
//| :param int y2: Maximum y-value (exclusive) for rectangular bounding box to be copied from the source bitmap. If unspecified or `None`, the source bitmap height is used.
10541038
//| :param int skip_source_index: bitmap palette index in the source that will not be copied,
10551039
//| set to None to copy all pixels
10561040
//| :param int skip_dest_index: bitmap palette index in the destination bitmap that will not get overwritten
@@ -1064,10 +1048,7 @@ STATIC mp_obj_t bitmaptools_obj_blit(size_t n_args, const mp_obj_t *pos_args, mp
10641048
{MP_QSTR_source_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
10651049
{MP_QSTR_x, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL} },
10661050
{MP_QSTR_y, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL} },
1067-
{MP_QSTR_x1, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
1068-
{MP_QSTR_y1, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
1069-
{MP_QSTR_x2, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, // None convert to source->width
1070-
{MP_QSTR_y2, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, // None convert to source->height
1051+
ALLOWED_ARGS_X1_Y1_X2_Y2(0, 0),
10711052
{MP_QSTR_skip_source_index, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
10721053
{MP_QSTR_skip_dest_index, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
10731054
};
@@ -1079,10 +1060,10 @@ STATIC mp_obj_t bitmaptools_obj_blit(size_t n_args, const mp_obj_t *pos_args, mp
10791060
displayio_bitmap_t *destination = mp_arg_validate_type(args[ARG_destination].u_obj, &displayio_bitmap_type, MP_QSTR_dest_bitmap);
10801061
// check_for_deinit(destination);
10811062

1082-
// Check x,y are within self (target) bitmap boundary
1083-
int16_t x = mp_arg_validate_int_range(args[ARG_x].u_int, 0, MAX(0, destination->width - 1), MP_QSTR_x);
1084-
int16_t y = mp_arg_validate_int_range(args[ARG_y].u_int, 0, MAX(0, destination->height - 1), MP_QSTR_y);
1063+
uint16_t x = mp_arg_validate_int_range(args[ARG_x].u_int, 0, destination->width, MP_QSTR_x);
1064+
uint16_t y = mp_arg_validate_int_range(args[ARG_y].u_int, 0, destination->height, MP_QSTR_y);
10851065

1066+
bitmaptools_rect_t lim = bitmaptools_validate_coord_range_pair(&args[ARG_x1], destination->width, destination->height);
10861067

10871068
displayio_bitmap_t *source = mp_arg_validate_type(args[ARG_source].u_obj, &displayio_bitmap_type, MP_QSTR_source_bitmap);
10881069

@@ -1092,35 +1073,6 @@ STATIC mp_obj_t bitmaptools_obj_blit(size_t n_args, const mp_obj_t *pos_args, mp
10921073
mp_raise_ValueError(MP_ERROR_TEXT("source palette too large"));
10931074
}
10941075

1095-
// Check x1,y1,x2,y2 are within source bitmap boundary
1096-
int16_t x1 = mp_arg_validate_int_range(args[ARG_x1].u_int, 0, MAX(0, source->width - 1), MP_QSTR_x1);
1097-
int16_t y1 = mp_arg_validate_int_range(args[ARG_y1].u_int, 0, MAX(0, source->height - 1), MP_QSTR_y1);
1098-
int16_t x2, y2;
1099-
// if x2 or y2 is None, then set as the maximum size of the source bitmap
1100-
if (args[ARG_x2].u_obj == mp_const_none) {
1101-
x2 = source->width;
1102-
} else {
1103-
x2 = mp_arg_validate_int_range(mp_obj_get_int(args[ARG_x2].u_obj), 0, source->width, MP_QSTR_x2);
1104-
}
1105-
// int16_t y2;
1106-
if (args[ARG_y2].u_obj == mp_const_none) {
1107-
y2 = source->height;
1108-
} else {
1109-
y2 = mp_arg_validate_int_range(mp_obj_get_int(args[ARG_y2].u_obj), 0, source->height, MP_QSTR_y2);
1110-
}
1111-
1112-
// Ensure x1 < x2 and y1 < y2
1113-
if (x1 > x2) {
1114-
int16_t temp = x2;
1115-
x2 = x1;
1116-
x1 = temp;
1117-
}
1118-
if (y1 > y2) {
1119-
int16_t temp = y2;
1120-
y2 = y1;
1121-
y1 = temp;
1122-
}
1123-
11241076
uint32_t skip_source_index;
11251077
bool skip_source_index_none; // flag whether skip_value was None
11261078

@@ -1143,7 +1095,7 @@ STATIC mp_obj_t bitmaptools_obj_blit(size_t n_args, const mp_obj_t *pos_args, mp
11431095
skip_dest_index_none = false;
11441096
}
11451097

1146-
common_hal_bitmaptools_blit(destination, source, x, y, x1, y1, x2, y2, skip_source_index, skip_source_index_none, skip_dest_index,
1098+
common_hal_bitmaptools_blit(destination, source, x, y, lim.x1, lim.y1, lim.x2, lim.y2, skip_source_index, skip_source_index_none, skip_dest_index,
11471099
skip_dest_index_none);
11481100

11491101
return mp_const_none;

0 commit comments

Comments
 (0)