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,7 +2733,7 @@ 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 // False == Image is black, True == rect valid
bool imlib_draw_image_rectangle(image_t *dst_img, void imlib_draw_image_get_bounds(image_t *dst_img,
image_t *src_img, image_t *src_img,
int dst_x_start, int dst_x_start,
int dst_y_start, int dst_y_start,
@ -2743,12 +2743,12 @@ bool imlib_draw_image_rectangle(image_t *dst_img,
int alpha, int alpha,
const uint8_t *alpha_palette, const uint8_t *alpha_palette,
image_hint_t hint, image_hint_t hint,
int *x0, point_t *p0,
int *x1, point_t *p1) {
int *y0, p0->x = -1;
int *y1) {
if (!alpha) { if (!alpha) {
return false; return;
} }
if (alpha_palette) { if (alpha_palette) {
@ -2758,7 +2758,7 @@ bool imlib_draw_image_rectangle(image_t *dst_img,
} }
if (i == 256) { if (i == 256) {
// zero alpha palette // 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) { if (dst_x_start >= dst_img->w) {
return false; return;
} }
int src_x_dst_width = src_width_scaled - src_x_start; int src_x_dst_width = src_width_scaled - src_x_start;
if (src_x_dst_width <= 0) { if (src_x_dst_width <= 0) {
return false; return;
} }
// Clamp start y to image bounds. // 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) { if (dst_y_start >= dst_img->h) {
return false; return;
} }
int src_y_dst_height = src_height_scaled - src_y_start; int src_y_dst_height = src_height_scaled - src_y_start;
if (src_y_dst_height <= 0) { if (src_y_dst_height <= 0) {
return false; return;
} }
// Clamp end x to image bounds. // 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; dst_y_end = dst_img->h;
} }
*x0 = dst_x_start; p0->x = dst_x_start;
*x1 = dst_x_end; p1->x = dst_x_end;
*y0 = dst_y_start; p0->y = dst_y_start;
*y1 = dst_y_end; p1->y = dst_y_end;
return true; return;
} }
void imlib_draw_image(image_t *dst_img, void imlib_draw_image(image_t *dst_img,

View File

@ -1274,7 +1274,7 @@ void imlib_draw_row_deinit_all();
void *imlib_draw_row_get_row_buffer(imlib_draw_row_data_t *data); 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_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); 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, void imlib_draw_image_get_bounds(image_t *dst_img,
image_t *src_img, image_t *src_img,
int dst_x_start, int dst_x_start,
int dst_y_start, int dst_y_start,
@ -1284,10 +1284,8 @@ bool imlib_draw_image_rectangle(image_t *dst_img,
int alpha, int alpha,
const uint8_t *alpha_palette, const uint8_t *alpha_palette,
image_hint_t hint, image_hint_t hint,
int *x0, point_t *p0,
int *x1, point_t *p1);
int *y0,
int *y1);
void imlib_flood_fill_int(image_t *out, image_t *img, int x, int y, void imlib_flood_fill_int(image_t *out, image_t *img, int x, int y,
int seed_threshold, int floating_threshold, int seed_threshold, int floating_threshold,
flood_fill_call_back_t cb, void *data); 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_x = fast_floorf((width - (roi->w * scale)) / 2);
int center_y = fast_floorf((height - (roi->h * scale)) / 2); int center_y = fast_floorf((height - (roi->h * scale)) / 2);
int x0, x1, y0, y1; point_t p0, p1;
bool black = !imlib_draw_image_rectangle(&temp, img, center_x, center_y, scale, scale, roi, imlib_draw_image_get_bounds(&temp, img, center_x, center_y, scale, scale, roi,
alpha, alpha_palette, hint, &x0, &x1, &y0, &y1); alpha, alpha_palette, hint, &p0, &p1);
bool black = p0.x == -1;
if (black) { if (black) {
// zero the whole image // zero the whole image
memset(temp.data, 0, temp.w * temp.h * sizeof(uint16_t)); memset(temp.data, 0, temp.w * temp.h * sizeof(uint16_t));
} else { } else {
// Zero the top rows // Zero the top rows
if (y0) { if (p0.y) {
memset(temp.data, 0, temp.w * y0 * sizeof(uint16_t)); memset(temp.data, 0, temp.w * p0.y * sizeof(uint16_t));
} }
if (x0) { if (p0.x) {
for (int i = y0; i < y1; i++) { for (int i = p0.y; i < p1.y; i++) {
// Zero left // 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, (hint & (~IMAGE_HINT_CENTER)) | IMAGE_HINT_BLACK_BACKGROUND,
NULL, NULL); NULL, NULL);
if (temp.w - x1) { if (temp.w - p1.x) {
for (int i = y0; i < y1; i++) { for (int i = p0.y; i < p1.y; i++) {
// Zero right // Zero right
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&temp, i) + x1, memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&temp, i) + p1.x,
0, (temp.w - x1) * sizeof(uint16_t)); 0, (temp.w - p1.x) * sizeof(uint16_t));
} }
} }
// Zero the bottom rows // Zero the bottom rows
if (temp.h - y1) { if (temp.h - p1.y) {
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&temp, y1), memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&temp, p1.y),
0, temp.w * (temp.h - y1) * sizeof(uint16_t)); 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.h = self->height;
dst_img.pixfmt = PIXFORMAT_RGB565; dst_img.pixfmt = PIXFORMAT_RGB565;
int x0, x1, y0, y1; point_t p0, p1;
bool black = !imlib_draw_image_rectangle(&dst_img, src_img, dst_x_start, dst_y_start, x_scale, imlib_draw_image_get_bounds(&dst_img, src_img, dst_x_start, dst_y_start, x_scale,
y_scale, roi, alpha, alpha_palette, hint, &x0, &x1, &y0, &y1); y_scale, roi, alpha, alpha_palette, hint, &p0, &p1);
bool black = p0.x == -1;
if (!self->triple_buffer) { if (!self->triple_buffer) {
dst_img.data = fb_alloc0(self->width * sizeof(uint16_t), FB_ALLOC_NO_HINT); 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 { } else {
// Zero the top rows // 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); 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, 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); hint | IMAGE_HINT_BLACK_BACKGROUND, spi_display_draw_image_cb, dst_img.data);
// Zero the bottom rows // Zero the bottom rows
if (y1 < self->height) { if (p1.y < self->height) {
memset(dst_img.data, 0, self->width * sizeof(uint16_t)); 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); 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)); memset(dst_img.data, 0, self->width * self->height * sizeof(uint16_t));
} else { } else {
// Zero the top rows // Zero the top rows
if (y0) { if (p0.y) {
memset(dst_img.data, 0, self->width * y0 * sizeof(uint16_t)); memset(dst_img.data, 0, self->width * p0.y * sizeof(uint16_t));
} }
if (x0) { if (p0.x) {
for (int i = y0; i < y1; i++) { for (int i = p0.y; i < p1.y; i++) {
// Zero left // 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, x_scale, y_scale, roi, rgb_channel, alpha, color_palette,
alpha_palette, hint | IMAGE_HINT_BLACK_BACKGROUND, NULL, NULL); alpha_palette, hint | IMAGE_HINT_BLACK_BACKGROUND, NULL, NULL);
if (self->width - x1) { if (self->width - p1.x) {
for (int i = y0; i < y1; i++) { for (int i = p0.y; i < p1.y; i++) {
// Zero right // 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 // Zero the bottom rows
if (self->height - y1) { if (self->height - p1.y) {
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, y1), memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, p1.y),
0, self->width * (self->height - y1) * sizeof(uint16_t)); 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.h = TV_HEIGHT;
dst_img.pixfmt = rgb565 ? PIXFORMAT_RGB565 : PIXFORMAT_GRAYSCALE; dst_img.pixfmt = rgb565 ? PIXFORMAT_RGB565 : PIXFORMAT_GRAYSCALE;
int x0, x1, y0, y1; point_t p0, p1;
bool black = !imlib_draw_image_rectangle(&dst_img, src_img, dst_x_start, dst_y_start, x_scale, y_scale, imlib_draw_image_get_bounds(&dst_img, src_img, dst_x_start, dst_y_start, x_scale, y_scale,
roi, alpha, alpha_palette, hint, &x0, &x1, &y0, &y1); roi, alpha, alpha_palette, hint, &p0, &p1);
bool black = p0.x == -1;
if (!tv_triple_buffer) { if (!tv_triple_buffer) {
dst_img.data = fb_alloc0(TV_WIDTH_RGB565, FB_ALLOC_NO_HINT); 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 { } else {
// Zero the top rows // 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); 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); cb, dst_img.data);
// Zero the bottom rows // Zero the bottom rows
if (y1 < TV_HEIGHT) { if (p1.y < TV_HEIGHT) {
memset(dst_img.data, 0, TV_WIDTH_RGB565); 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); 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)); memset(dst_img.data, 0, TV_WIDTH * TV_HEIGHT * sizeof(uint16_t));
} else { } else {
// Zero the top rows // Zero the top rows
if (y0) { if (p0.y) {
memset(dst_img.data, 0, TV_WIDTH * y0 * sizeof(uint16_t)); memset(dst_img.data, 0, TV_WIDTH * p0.y * sizeof(uint16_t));
} }
if (x0) { if (p0.x) {
for (int i = y0; i < y1; i++) { for (int i = p0.y; i < p1.y; i++) {
// Zero left // 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, rgb_channel, alpha, color_palette, alpha_palette, hint | IMAGE_HINT_BLACK_BACKGROUND,
NULL, NULL); NULL, NULL);
if (TV_WIDTH - x1) { if (TV_WIDTH - p1.x) {
for (int i = y0; i < y1; i++) { for (int i = p0.y; i < p1.y; i++) {
// Zero right // Zero right
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, i) + x1, 0, memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, i) + p1.x, 0,
(TV_WIDTH - x1) * sizeof(uint16_t)); (TV_WIDTH - p1.x) * sizeof(uint16_t));
} }
} }
// Zero the bottom rows // Zero the bottom rows
if (TV_HEIGHT - y1) { if (TV_HEIGHT - p1.y) {
memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, y1), 0, memset(IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(&dst_img, p1.y), 0,
TV_WIDTH * (TV_HEIGHT - y1) * sizeof(uint16_t)); 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)); memset(dst_img.data, 0, TV_WIDTH * TV_HEIGHT * sizeof(uint8_t));
} else { } else {
// Zero the top rows // Zero the top rows
if (y0) { if (p0.y) {
memset(dst_img.data, 0, TV_WIDTH * y0 * sizeof(uint8_t)); memset(dst_img.data, 0, TV_WIDTH * p0.y * sizeof(uint8_t));
} }
if (x0) { if (p0.x) {
for (int i = y0; i < y1; i++) { for (int i = p0.y; i < p1.y; i++) {
// Zero left // 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, rgb_channel, alpha, color_palette, alpha_palette, hint | IMAGE_HINT_BLACK_BACKGROUND,
NULL, NULL); NULL, NULL);
if (TV_WIDTH - x1) { if (TV_WIDTH - p1.x) {
for (int i = y0; i < y1; i++) { for (int i = p0.y; i < p1.y; i++) {
// Zero right // Zero right
memset(IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&dst_img, i) + x1, 0, memset(IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&dst_img, i) + p1.x, 0,
(TV_WIDTH - x1) * sizeof(uint8_t)); (TV_WIDTH - p1.x) * sizeof(uint8_t));
} }
} }
// Zero the bottom rows // Zero the bottom rows
if (TV_HEIGHT - y1) { if (TV_HEIGHT - p1.y) {
memset(IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&dst_img, y1), 0, memset(IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(&dst_img, p1.y), 0,
TV_WIDTH * (TV_HEIGHT - y1) * sizeof(uint8_t)); 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.h = self->height;
dst_img.pixfmt = PIXFORMAT_RGB565; dst_img.pixfmt = PIXFORMAT_RGB565;
int x0, x1, y0, y1; point_t p0, p1;
bool black = !imlib_draw_image_rectangle(&dst_img, src_img, dst_x_start, dst_y_start, x_scale, y_scale, imlib_draw_image_get_bounds(&dst_img, src_img, dst_x_start, dst_y_start, x_scale, y_scale,
roi, alpha, alpha_palette, hint, &x0, &x1, &y0, &y1); 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 // For triple buffering we are never drawing where tail or head (which may instantly update to
// to be equal to tail) is. // 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]; dst_img.data = (uint8_t *) self->framebuffers[tail];
// Set default values for the layer to display the whole framebuffer. // Set default values for the layer to display the whole framebuffer.
display.framebuffer_layers[tail].WindowX0 = black ? 0 : x0; display.framebuffer_layers[tail].WindowX0 = black ? 0 : p0.x;
display.framebuffer_layers[tail].WindowX1 = black ? self->width : x1; display.framebuffer_layers[tail].WindowX1 = black ? self->width : p1.x;
display.framebuffer_layers[tail].WindowY0 = black ? 0 : y0; display.framebuffer_layers[tail].WindowY0 = black ? 0 : p0.y;
display.framebuffer_layers[tail].WindowY1 = black ? self->height : y1; 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].Alpha = black ? 0 : fast_roundf((alpha * 255) / 256.f);
display.framebuffer_layers[tail].FBStartAdress = 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].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. // 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) { if (!black) {