imlib: Refactor imlib_draw_image_rect.

This commit is contained in:
Kwabena W. Agyeman 2023-10-29 15:28:22 -07:00
parent 1f0b209750
commit 15c98c0762
6 changed files with 113 additions and 110 deletions

View File

@ -2733,22 +2733,22 @@ void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *da
}
// False == Image is black, True == rect valid
bool imlib_draw_image_rectangle(image_t *dst_img,
image_t *src_img,
int dst_x_start,
int dst_y_start,
float x_scale,
float y_scale,
rectangle_t *roi,
int alpha,
const uint8_t *alpha_palette,
image_hint_t hint,
int *x0,
int *x1,
int *y0,
int *y1) {
void imlib_draw_image_get_bounds(image_t *dst_img,
image_t *src_img,
int dst_x_start,
int dst_y_start,
float x_scale,
float y_scale,
rectangle_t *roi,
int alpha,
const uint8_t *alpha_palette,
image_hint_t hint,
point_t *p0,
point_t *p1) {
p0->x = -1;
if (!alpha) {
return false;
return;
}
if (alpha_palette) {
@ -2758,7 +2758,7 @@ bool imlib_draw_image_rectangle(image_t *dst_img,
}
if (i == 256) {
// zero alpha palette
return false;
return;
}
}
@ -2779,13 +2779,13 @@ bool imlib_draw_image_rectangle(image_t *dst_img,
}
if (dst_x_start >= dst_img->w) {
return false;
return;
}
int src_x_dst_width = src_width_scaled - src_x_start;
if (src_x_dst_width <= 0) {
return false;
return;
}
// Clamp start y to image bounds.
@ -2796,13 +2796,13 @@ bool imlib_draw_image_rectangle(image_t *dst_img,
}
if (dst_y_start >= dst_img->h) {
return false;
return;
}
int src_y_dst_height = src_height_scaled - src_y_start;
if (src_y_dst_height <= 0) {
return false;
return;
}
// Clamp end x to image bounds.
@ -2817,12 +2817,12 @@ bool imlib_draw_image_rectangle(image_t *dst_img,
dst_y_end = dst_img->h;
}
*x0 = dst_x_start;
*x1 = dst_x_end;
*y0 = dst_y_start;
*y1 = dst_y_end;
p0->x = dst_x_start;
p1->x = dst_x_end;
p0->y = dst_y_start;
p1->y = dst_y_end;
return true;
return;
}
void imlib_draw_image(image_t *dst_img,

View File

@ -1274,20 +1274,18 @@ void imlib_draw_row_deinit_all();
void *imlib_draw_row_get_row_buffer(imlib_draw_row_data_t *data);
void imlib_draw_row_put_row_buffer(imlib_draw_row_data_t *data, void *row_buffer);
void imlib_draw_row(int x_start, int x_end, int y_row, imlib_draw_row_data_t *data);
bool imlib_draw_image_rectangle(image_t *dst_img,
image_t *src_img,
int dst_x_start,
int dst_y_start,
float x_scale,
float y_scale,
rectangle_t *roi,
int alpha,
const uint8_t *alpha_palette,
image_hint_t hint,
int *x0,
int *x1,
int *y0,
int *y1);
void imlib_draw_image_get_bounds(image_t *dst_img,
image_t *src_img,
int dst_x_start,
int dst_y_start,
float x_scale,
float y_scale,
rectangle_t *roi,
int alpha,
const uint8_t *alpha_palette,
image_hint_t hint,
point_t *p0,
point_t *p1);
void imlib_flood_fill_int(image_t *out, image_t *img, int x, int y,
int seed_threshold, int floating_threshold,
flood_fill_call_back_t cb, void *data);

View File

@ -134,23 +134,24 @@ void mjpeg_write(FIL *fp, int width, int height, uint32_t *frames, uint32_t *byt
int center_x = fast_floorf((width - (roi->w * scale)) / 2);
int center_y = fast_floorf((height - (roi->h * scale)) / 2);
int x0, x1, y0, y1;
bool black = !imlib_draw_image_rectangle(&temp, img, center_x, center_y, scale, scale, roi,
alpha, alpha_palette, hint, &x0, &x1, &y0, &y1);
point_t p0, p1;
imlib_draw_image_get_bounds(&temp, img, center_x, center_y, scale, scale, roi,
alpha, alpha_palette, hint, &p0, &p1);
bool black = p0.x == -1;
if (black) {
// zero the whole image
memset(temp.data, 0, temp.w * temp.h * sizeof(uint16_t));
} else {
// Zero the top rows
if (y0) {
memset(temp.data, 0, temp.w * y0 * sizeof(uint16_t));
if (p0.y) {
memset(temp.data, 0, temp.w * p0.y * sizeof(uint16_t));
}
if (x0) {
for (int i = y0; i < y1; i++) {
if (p0.x) {
for (int i = p0.y; i < p1.y; i++) {
// Zero left
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&temp, i), 0, x0 * sizeof(uint16_t));
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&temp, i), 0, p0.x * sizeof(uint16_t));
}
}
@ -159,18 +160,18 @@ void mjpeg_write(FIL *fp, int width, int height, uint32_t *frames, uint32_t *byt
(hint & (~IMAGE_HINT_CENTER)) | IMAGE_HINT_BLACK_BACKGROUND,
NULL, NULL);
if (temp.w - x1) {
for (int i = y0; i < y1; i++) {
if (temp.w - p1.x) {
for (int i = p0.y; i < p1.y; i++) {
// Zero right
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&temp, i) + x1,
0, (temp.w - x1) * sizeof(uint16_t));
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&temp, i) + p1.x,
0, (temp.w - p1.x) * sizeof(uint16_t));
}
}
// Zero the bottom rows
if (temp.h - y1) {
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&temp, y1),
0, temp.w * (temp.h - y1) * sizeof(uint16_t));
if (temp.h - p1.y) {
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&temp, p1.y),
0, temp.w * (temp.h - p1.y) * sizeof(uint16_t));
}
}
}

View File

@ -172,9 +172,10 @@ static void spi_display_write(py_display_obj_t *self, image_t *src_img, int dst_
dst_img.h = self->height;
dst_img.pixfmt = PIXFORMAT_RGB565;
int x0, x1, y0, y1;
bool black = !imlib_draw_image_rectangle(&dst_img, src_img, dst_x_start, dst_y_start, x_scale,
y_scale, roi, alpha, alpha_palette, hint, &x0, &x1, &y0, &y1);
point_t p0, p1;
imlib_draw_image_get_bounds(&dst_img, src_img, dst_x_start, dst_y_start, x_scale,
y_scale, roi, alpha, alpha_palette, hint, &p0, &p1);
bool black = p0.x == -1;
if (!self->triple_buffer) {
dst_img.data = fb_alloc0(self->width * sizeof(uint16_t), FB_ALLOC_NO_HINT);
@ -190,7 +191,7 @@ static void spi_display_write(py_display_obj_t *self, image_t *src_img, int dst_
}
} else {
// Zero the top rows
for (int i = 0; i < y0; i++) {
for (int i = 0; i < p0.y; i++) {
spi_transmit_16(self, dst_img.data, self->width);
}
@ -202,11 +203,11 @@ static void spi_display_write(py_display_obj_t *self, image_t *src_img, int dst_
x_scale, y_scale, roi, rgb_channel, alpha, color_palette, alpha_palette,
hint | IMAGE_HINT_BLACK_BACKGROUND, spi_display_draw_image_cb, dst_img.data);
// Zero the bottom rows
if (y1 < self->height) {
if (p1.y < self->height) {
memset(dst_img.data, 0, self->width * sizeof(uint16_t));
}
for (int i = y1; i < self->height; i++) {
for (int i = p1.y; i < self->height; i++) {
spi_transmit_16(self, dst_img.data, self->width);
}
}
@ -229,14 +230,14 @@ static void spi_display_write(py_display_obj_t *self, image_t *src_img, int dst_
memset(dst_img.data, 0, self->width * self->height * sizeof(uint16_t));
} else {
// Zero the top rows
if (y0) {
memset(dst_img.data, 0, self->width * y0 * sizeof(uint16_t));
if (p0.y) {
memset(dst_img.data, 0, self->width * p0.y * sizeof(uint16_t));
}
if (x0) {
for (int i = y0; i < y1; i++) {
if (p0.x) {
for (int i = p0.y; i < p1.y; i++) {
// Zero left
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, i), 0, x0 * sizeof(uint16_t));
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, i), 0, p0.x * sizeof(uint16_t));
}
}
@ -244,17 +245,18 @@ static void spi_display_write(py_display_obj_t *self, image_t *src_img, int dst_
x_scale, y_scale, roi, rgb_channel, alpha, color_palette,
alpha_palette, hint | IMAGE_HINT_BLACK_BACKGROUND, NULL, NULL);
if (self->width - x1) {
for (int i = y0; i < y1; i++) {
if (self->width - p1.x) {
for (int i = p0.y; i < p1.y; i++) {
// Zero right
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, i) + x1, 0, (self->width - x1) * sizeof(uint16_t));
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, i) + p1.x, 0,
(self->width - p1.x) * sizeof(uint16_t));
}
}
// Zero the bottom rows
if (self->height - y1) {
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, y1),
0, self->width * (self->height - y1) * sizeof(uint16_t));
if (self->height - p1.y) {
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, p1.y),
0, self->width * (self->height - p1.y) * sizeof(uint16_t));
}
}

View File

@ -588,9 +588,10 @@ static void spi_tv_display(image_t *src_img, int dst_x_start, int dst_y_start, f
dst_img.h = TV_HEIGHT;
dst_img.pixfmt = rgb565 ? PIXFORMAT_RGB565 : PIXFORMAT_GRAYSCALE;
int x0, x1, y0, y1;
bool black = !imlib_draw_image_rectangle(&dst_img, src_img, dst_x_start, dst_y_start, x_scale, y_scale,
roi, alpha, alpha_palette, hint, &x0, &x1, &y0, &y1);
point_t p0, p1;
imlib_draw_image_get_bounds(&dst_img, src_img, dst_x_start, dst_y_start, x_scale, y_scale,
roi, alpha, alpha_palette, hint, &p0, &p1);
bool black = p0.x == -1;
if (!tv_triple_buffer) {
dst_img.data = fb_alloc0(TV_WIDTH_RGB565, FB_ALLOC_NO_HINT);
@ -604,7 +605,7 @@ static void spi_tv_display(image_t *src_img, int dst_x_start, int dst_y_start, f
}
} else {
// Zero the top rows
for (int i = 0; i < y0; i++) {
for (int i = 0; i < p0.y; i++) {
SpiTransmitReceivePacket(dst_img.data, NULL, PICLINE_LENGTH_BYTES, false);
}
@ -614,11 +615,11 @@ static void spi_tv_display(image_t *src_img, int dst_x_start, int dst_y_start, f
cb, dst_img.data);
// Zero the bottom rows
if (y1 < TV_HEIGHT) {
if (p1.y < TV_HEIGHT) {
memset(dst_img.data, 0, TV_WIDTH_RGB565);
}
for (int i = y1; i < TV_HEIGHT; i++) {
for (int i = p1.y; i < TV_HEIGHT; i++) {
SpiTransmitReceivePacket(dst_img.data, NULL, PICLINE_LENGTH_BYTES, false);
}
}
@ -641,14 +642,14 @@ static void spi_tv_display(image_t *src_img, int dst_x_start, int dst_y_start, f
memset(dst_img.data, 0, TV_WIDTH * TV_HEIGHT * sizeof(uint16_t));
} else {
// Zero the top rows
if (y0) {
memset(dst_img.data, 0, TV_WIDTH * y0 * sizeof(uint16_t));
if (p0.y) {
memset(dst_img.data, 0, TV_WIDTH * p0.y * sizeof(uint16_t));
}
if (x0) {
for (int i = y0; i < y1; i++) {
if (p0.x) {
for (int i = p0.y; i < p1.y; i++) {
// Zero left
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, i), 0, x0 * sizeof(uint16_t));
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, i), 0, p0.x * sizeof(uint16_t));
}
}
@ -656,18 +657,18 @@ static void spi_tv_display(image_t *src_img, int dst_x_start, int dst_y_start, f
rgb_channel, alpha, color_palette, alpha_palette, hint | IMAGE_HINT_BLACK_BACKGROUND,
NULL, NULL);
if (TV_WIDTH - x1) {
for (int i = y0; i < y1; i++) {
if (TV_WIDTH - p1.x) {
for (int i = p0.y; i < p1.y; i++) {
// Zero right
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, i) + x1, 0,
(TV_WIDTH - x1) * sizeof(uint16_t));
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, i) + p1.x, 0,
(TV_WIDTH - p1.x) * sizeof(uint16_t));
}
}
// Zero the bottom rows
if (TV_HEIGHT - y1) {
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, y1), 0,
TV_WIDTH * (TV_HEIGHT - y1) * sizeof(uint16_t));
if (TV_HEIGHT - p1.y) {
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, p1.y), 0,
TV_WIDTH * (TV_HEIGHT - p1.y) * sizeof(uint16_t));
}
}
@ -682,14 +683,14 @@ static void spi_tv_display(image_t *src_img, int dst_x_start, int dst_y_start, f
memset(dst_img.data, 0, TV_WIDTH * TV_HEIGHT * sizeof(uint8_t));
} else {
// Zero the top rows
if (y0) {
memset(dst_img.data, 0, TV_WIDTH * y0 * sizeof(uint8_t));
if (p0.y) {
memset(dst_img.data, 0, TV_WIDTH * p0.y * sizeof(uint8_t));
}
if (x0) {
for (int i = y0; i < y1; i++) {
if (p0.x) {
for (int i = p0.y; i < p1.y; i++) {
// Zero left
memset(IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&dst_img, i), 0, x0 * sizeof(uint8_t));
memset(IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&dst_img, i), 0, p0.x * sizeof(uint8_t));
}
}
@ -697,18 +698,18 @@ static void spi_tv_display(image_t *src_img, int dst_x_start, int dst_y_start, f
rgb_channel, alpha, color_palette, alpha_palette, hint | IMAGE_HINT_BLACK_BACKGROUND,
NULL, NULL);
if (TV_WIDTH - x1) {
for (int i = y0; i < y1; i++) {
if (TV_WIDTH - p1.x) {
for (int i = p0.y; i < p1.y; i++) {
// Zero right
memset(IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&dst_img, i) + x1, 0,
(TV_WIDTH - x1) * sizeof(uint8_t));
memset(IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&dst_img, i) + p1.x, 0,
(TV_WIDTH - p1.x) * sizeof(uint8_t));
}
}
// Zero the bottom rows
if (TV_HEIGHT - y1) {
memset(IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&dst_img, y1), 0,
TV_WIDTH * (TV_HEIGHT - y1) * sizeof(uint8_t));
if (TV_HEIGHT - p1.y) {
memset(IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&dst_img, p1.y), 0,
TV_WIDTH * (TV_HEIGHT - p1.y) * sizeof(uint8_t));
}
}

View File

@ -409,9 +409,10 @@ static void display_write(py_display_obj_t *self, image_t *src_img, int dst_x_st
dst_img.h = self->height;
dst_img.pixfmt = PIXFORMAT_RGB565;
int x0, x1, y0, y1;
bool black = !imlib_draw_image_rectangle(&dst_img, src_img, dst_x_start, dst_y_start, x_scale, y_scale,
roi, alpha, alpha_palette, hint, &x0, &x1, &y0, &y1);
point_t p0, p1;
imlib_draw_image_get_bounds(&dst_img, src_img, dst_x_start, dst_y_start, x_scale, y_scale,
roi, alpha, alpha_palette, hint, &p0, &p1);
bool black = p0.x == -1;
// For triple buffering we are never drawing where tail or head (which may instantly update to
// to be equal to tail) is.
@ -422,15 +423,15 @@ static void display_write(py_display_obj_t *self, image_t *src_img, int dst_x_st
dst_img.data = (uint8_t *) self->framebuffers[tail];
// Set default values for the layer to display the whole framebuffer.
display.framebuffer_layers[tail].WindowX0 = black ? 0 : x0;
display.framebuffer_layers[tail].WindowX1 = black ? self->width : x1;
display.framebuffer_layers[tail].WindowY0 = black ? 0 : y0;
display.framebuffer_layers[tail].WindowY1 = black ? self->height : y1;
display.framebuffer_layers[tail].WindowX0 = black ? 0 : p0.x;
display.framebuffer_layers[tail].WindowX1 = black ? self->width : p1.x;
display.framebuffer_layers[tail].WindowY0 = black ? 0 : p0.y;
display.framebuffer_layers[tail].WindowY1 = black ? self->height : p1.y;
display.framebuffer_layers[tail].Alpha = black ? 0 : fast_roundf((alpha * 255) / 256.f);
display.framebuffer_layers[tail].FBStartAdress =
black ? ((uint32_t) dst_img.data) : ((uint32_t) (IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, y0) + x0));
black ? ((uint32_t) dst_img.data) : ((uint32_t) (IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, p0.y) + p0.x));
display.framebuffer_layers[tail].ImageWidth = black ? self->width : dst_img.w;
display.framebuffer_layers[tail].ImageHeight = black ? self->height : (y1 - y0);
display.framebuffer_layers[tail].ImageHeight = black ? self->height : (p1.y - p0.y);
// Set alpha to 256 here as we will use the layer alpha to blend the image into the background color of black for free.
if (!black) {