mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Update draw image to support in place updates
This commit is contained in:
parent
6fa0b9f478
commit
01aad01c49
@ -439,7 +439,14 @@ void imlib_draw_string(image_t *img, int x_off, int y_off, const char *str, int
|
|||||||
|
|
||||||
void imlib_draw_row_setup(imlib_draw_row_data_t *data)
|
void imlib_draw_row_setup(imlib_draw_row_data_t *data)
|
||||||
{
|
{
|
||||||
size_t image_row_size = image_size(data->dst_img) / data->dst_img->h;
|
image_t temp;
|
||||||
|
temp.w = data->dst_img->w;
|
||||||
|
temp.h = data->dst_img->h;
|
||||||
|
temp.bpp = data->src_img_bpp;
|
||||||
|
|
||||||
|
// Image Row Size should be the width of the destination image
|
||||||
|
// but with the bpp of the source image.
|
||||||
|
size_t image_row_size = image_size(&temp) / data->dst_img->h;
|
||||||
|
|
||||||
data->toggle = 0;
|
data->toggle = 0;
|
||||||
data->row_buffer[0] = fb_alloc(image_row_size, FB_ALLOC_NO_HINT);
|
data->row_buffer[0] = fb_alloc(image_row_size, FB_ALLOC_NO_HINT);
|
||||||
@ -2663,6 +2670,29 @@ void imlib_draw_image(image_t *dst_img, image_t *src_img, int dst_x_start, int d
|
|||||||
color_palette = NULL;
|
color_palette = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool no_scaling_nearest_neighbor = (dst_delta_x == 1)
|
||||||
|
&& (dst_x_start == 0) && (src_x_start == 0)
|
||||||
|
&& (src_x_frac == 65536) && (src_y_frac == 65536);
|
||||||
|
|
||||||
|
// If we are scaling just make a deep copy.
|
||||||
|
bool is_scaling = (hint & (IMAGE_HINT_AREA | IMAGE_HINT_BICUBIC | IMAGE_HINT_BILINEAR))
|
||||||
|
|| (!no_scaling_nearest_neighbor);
|
||||||
|
|
||||||
|
// Otherwise, we only have to do a deep copy if the image is growing.
|
||||||
|
size_t src_img_row_bytes = image_size(src_img) / src_img->h;
|
||||||
|
size_t dst_img_row_bytes = image_size(dst_img) / dst_img->h;
|
||||||
|
|
||||||
|
// In-place (by definition mutually exclusive to the above)...
|
||||||
|
if ((dst_img->data == src_img->data) && (is_scaling || (src_img_row_bytes < dst_img_row_bytes))) {
|
||||||
|
size_t size = image_size(src_img);
|
||||||
|
new_src_img.w = src_img->w; // same width as source image
|
||||||
|
new_src_img.h = src_img->h; // same height as source image
|
||||||
|
new_src_img.bpp = src_img->bpp;
|
||||||
|
new_src_img.data = fb_alloc(size, FB_ALLOC_NO_HINT);
|
||||||
|
memcpy(new_src_img.data, src_img->data, size);
|
||||||
|
src_img = &new_src_img;
|
||||||
|
}
|
||||||
|
|
||||||
imlib_draw_row_data_t imlib_draw_row_data;
|
imlib_draw_row_data_t imlib_draw_row_data;
|
||||||
imlib_draw_row_data.dst_img = dst_img;
|
imlib_draw_row_data.dst_img = dst_img;
|
||||||
imlib_draw_row_data.src_img_bpp = src_img->bpp;
|
imlib_draw_row_data.src_img_bpp = src_img->bpp;
|
||||||
@ -4360,52 +4390,162 @@ void imlib_draw_image(image_t *dst_img, image_t *src_img, int dst_x_start, int d
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ((dst_delta_x == 1) && (dst_x_start == 0) && (src_x_start == 0) && (src_x_frac == 65536) && (src_y_frac == 65536)) { // copy
|
} else if (no_scaling_nearest_neighbor) { // copy
|
||||||
switch (src_img->bpp) {
|
if (dst_img->data == src_img->data) { // In-Place
|
||||||
case IMAGE_BPP_BINARY: {
|
switch (src_img->bpp) {
|
||||||
while (y_not_done) {
|
case IMAGE_BPP_BINARY: {
|
||||||
uint32_t *src_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
while (y_not_done) {
|
||||||
imlib_draw_row_put_row_buffer(&imlib_draw_row_data, src_row_ptr);
|
uint32_t *src_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
||||||
imlib_draw_row(dst_x_start, dst_x_end, dst_y, &imlib_draw_row_data);
|
// Must be called per loop to get the address of the temp buffer to blend with
|
||||||
|
uint32_t *dst_row_ptr = (uint32_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
||||||
|
|
||||||
// Increment offsets
|
// X loop iteration variables
|
||||||
dst_y += dst_delta_y;
|
int dst_x = dst_x_reset;
|
||||||
src_y_accum += src_y_frac;
|
long src_x_accum = src_x_accum_reset;
|
||||||
next_src_y_index = src_y_accum >> 16;
|
int next_src_x_index = src_x_accum >> 16;
|
||||||
y_not_done = ++y < dst_y_end;
|
int x = dst_x_start;
|
||||||
} // while y
|
bool x_not_done = x < dst_x_end;
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IMAGE_BPP_GRAYSCALE: {
|
|
||||||
while (y_not_done) {
|
|
||||||
uint8_t *src_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
|
||||||
imlib_draw_row_put_row_buffer(&imlib_draw_row_data, src_row_ptr);
|
|
||||||
imlib_draw_row(dst_x_start, dst_x_end, dst_y, &imlib_draw_row_data);
|
|
||||||
|
|
||||||
// Increment offsets
|
while (x_not_done) {
|
||||||
dst_y += dst_delta_y;
|
int pixel = IMAGE_GET_BINARY_PIXEL_FAST(src_row_ptr, next_src_x_index);
|
||||||
src_y_accum += src_y_frac;
|
IMAGE_PUT_BINARY_PIXEL_FAST(dst_row_ptr, dst_x, pixel);
|
||||||
next_src_y_index = src_y_accum >> 16;
|
|
||||||
y_not_done = ++y < dst_y_end;
|
|
||||||
} // while y
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case IMAGE_BPP_RGB565: {
|
|
||||||
while (y_not_done) {
|
|
||||||
uint16_t *src_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
|
||||||
imlib_draw_row_put_row_buffer(&imlib_draw_row_data, src_row_ptr);
|
|
||||||
imlib_draw_row(dst_x_start, dst_x_end, dst_y, &imlib_draw_row_data);
|
|
||||||
|
|
||||||
// Increment offsets
|
// Increment offsets
|
||||||
dst_y += dst_delta_y;
|
dst_x += dst_delta_x;
|
||||||
src_y_accum += src_y_frac;
|
src_x_accum += src_x_frac;
|
||||||
next_src_y_index = src_y_accum >> 16;
|
next_src_x_index = src_x_accum >> 16;
|
||||||
y_not_done = ++y < dst_y_end;
|
x_not_done = ++x < dst_x_end;
|
||||||
} // while y
|
} // while x
|
||||||
break;
|
|
||||||
|
imlib_draw_row(dst_x_start, dst_x_end, dst_y, &imlib_draw_row_data);
|
||||||
|
|
||||||
|
// Increment offsets
|
||||||
|
dst_y += dst_delta_y;
|
||||||
|
src_y_accum += src_y_frac;
|
||||||
|
next_src_y_index = src_y_accum >> 16;
|
||||||
|
y_not_done = ++y < dst_y_end;
|
||||||
|
} // while y
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IMAGE_BPP_GRAYSCALE: {
|
||||||
|
while (y_not_done) {
|
||||||
|
uint8_t *src_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
||||||
|
// Must be called per loop to get the address of the temp buffer to blend with
|
||||||
|
uint8_t *dst_row_ptr = (uint8_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
||||||
|
|
||||||
|
// X loop iteration variables
|
||||||
|
int dst_x = dst_x_reset;
|
||||||
|
long src_x_accum = src_x_accum_reset;
|
||||||
|
int next_src_x_index = src_x_accum >> 16;
|
||||||
|
int x = dst_x_start;
|
||||||
|
bool x_not_done = x < dst_x_end;
|
||||||
|
|
||||||
|
while (x_not_done) {
|
||||||
|
int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(src_row_ptr, next_src_x_index);
|
||||||
|
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(dst_row_ptr, dst_x, pixel);
|
||||||
|
|
||||||
|
// Increment offsets
|
||||||
|
dst_x += dst_delta_x;
|
||||||
|
src_x_accum += src_x_frac;
|
||||||
|
next_src_x_index = src_x_accum >> 16;
|
||||||
|
x_not_done = ++x < dst_x_end;
|
||||||
|
} // while x
|
||||||
|
|
||||||
|
imlib_draw_row(dst_x_start, dst_x_end, dst_y, &imlib_draw_row_data);
|
||||||
|
|
||||||
|
// Increment offsets
|
||||||
|
dst_y += dst_delta_y;
|
||||||
|
src_y_accum += src_y_frac;
|
||||||
|
next_src_y_index = src_y_accum >> 16;
|
||||||
|
y_not_done = ++y < dst_y_end;
|
||||||
|
} // while y
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IMAGE_BPP_RGB565: {
|
||||||
|
while (y_not_done) {
|
||||||
|
uint16_t *src_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
||||||
|
// Must be called per loop to get the address of the temp buffer to blend with
|
||||||
|
uint16_t *dst_row_ptr = (uint16_t *) imlib_draw_row_get_row_buffer(&imlib_draw_row_data);
|
||||||
|
|
||||||
|
// X loop iteration variables
|
||||||
|
int dst_x = dst_x_reset;
|
||||||
|
long src_x_accum = src_x_accum_reset;
|
||||||
|
int next_src_x_index = src_x_accum >> 16;
|
||||||
|
int x = dst_x_start;
|
||||||
|
bool x_not_done = x < dst_x_end;
|
||||||
|
|
||||||
|
while (x_not_done) {
|
||||||
|
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(src_row_ptr, next_src_x_index);
|
||||||
|
IMAGE_PUT_RGB565_PIXEL_FAST(dst_row_ptr, dst_x, pixel);
|
||||||
|
|
||||||
|
// Increment offsets
|
||||||
|
dst_x += dst_delta_x;
|
||||||
|
src_x_accum += src_x_frac;
|
||||||
|
next_src_x_index = src_x_accum >> 16;
|
||||||
|
x_not_done = ++x < dst_x_end;
|
||||||
|
} // while x
|
||||||
|
|
||||||
|
imlib_draw_row(dst_x_start, dst_x_end, dst_y, &imlib_draw_row_data);
|
||||||
|
|
||||||
|
// Increment offsets
|
||||||
|
dst_y += dst_delta_y;
|
||||||
|
src_y_accum += src_y_frac;
|
||||||
|
next_src_y_index = src_y_accum >> 16;
|
||||||
|
y_not_done = ++y < dst_y_end;
|
||||||
|
} // while y
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
default: {
|
} else { // Out-of-Place
|
||||||
break;
|
switch (src_img->bpp) {
|
||||||
|
case IMAGE_BPP_BINARY: {
|
||||||
|
while (y_not_done) {
|
||||||
|
uint32_t *src_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
||||||
|
imlib_draw_row_put_row_buffer(&imlib_draw_row_data, src_row_ptr);
|
||||||
|
imlib_draw_row(dst_x_start, dst_x_end, dst_y, &imlib_draw_row_data);
|
||||||
|
|
||||||
|
// Increment offsets
|
||||||
|
dst_y += dst_delta_y;
|
||||||
|
src_y_accum += src_y_frac;
|
||||||
|
next_src_y_index = src_y_accum >> 16;
|
||||||
|
y_not_done = ++y < dst_y_end;
|
||||||
|
} // while y
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IMAGE_BPP_GRAYSCALE: {
|
||||||
|
while (y_not_done) {
|
||||||
|
uint8_t *src_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
||||||
|
imlib_draw_row_put_row_buffer(&imlib_draw_row_data, src_row_ptr);
|
||||||
|
imlib_draw_row(dst_x_start, dst_x_end, dst_y, &imlib_draw_row_data);
|
||||||
|
|
||||||
|
// Increment offsets
|
||||||
|
dst_y += dst_delta_y;
|
||||||
|
src_y_accum += src_y_frac;
|
||||||
|
next_src_y_index = src_y_accum >> 16;
|
||||||
|
y_not_done = ++y < dst_y_end;
|
||||||
|
} // while y
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IMAGE_BPP_RGB565: {
|
||||||
|
while (y_not_done) {
|
||||||
|
uint16_t *src_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(src_img, next_src_y_index);
|
||||||
|
imlib_draw_row_put_row_buffer(&imlib_draw_row_data, src_row_ptr);
|
||||||
|
imlib_draw_row(dst_x_start, dst_x_end, dst_y, &imlib_draw_row_data);
|
||||||
|
|
||||||
|
// Increment offsets
|
||||||
|
dst_y += dst_delta_y;
|
||||||
|
src_y_accum += src_y_frac;
|
||||||
|
next_src_y_index = src_y_accum >> 16;
|
||||||
|
y_not_done = ++y < dst_y_end;
|
||||||
|
} // while y
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // nearest neighbor
|
} else { // nearest neighbor
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user