diff --git a/src/omv/imlib/imlib.h b/src/omv/imlib/imlib.h index 9d812ffd7..608f96b39 100644 --- a/src/omv/imlib/imlib.h +++ b/src/omv/imlib/imlib.h @@ -437,6 +437,24 @@ bool image_get_mask_pixel(image_t *ptr, int x, int y); (_image->bpp == IMAGE_BPP_BAYER); \ }) +#define IMAGE_IS_MUTABLE_BAYER_JPEG(image) \ +({ \ + __typeof__ (image) _image = (image); \ + (_image->bpp == IMAGE_BPP_BINARY) || \ + (_image->bpp == IMAGE_BPP_GRAYSCALE) || \ + (_image->bpp == IMAGE_BPP_RGB565) || \ + (_image->bpp == IMAGE_BPP_BAYER) || \ + (_image->bpp >= IMAGE_BPP_JPEG); \ +}) + +#define IMAGE_IS_COLOR(image) \ +({ \ + __typeof__ (image) _image = (image); \ + (_image->bpp == IMAGE_BPP_RGB565) || \ + (_image->bpp == IMAGE_BPP_BAYER) || \ + (_image->bpp >= IMAGE_BPP_JPEG); \ +}) + #define IMAGE_BINARY_LINE_LEN(image) (((image)->w + UINT32_T_MASK) >> UINT32_T_SHIFT) #define IMAGE_BINARY_LINE_LEN_BYTES(image) (IMAGE_BINARY_LINE_LEN(image) * sizeof(uint32_t)) diff --git a/src/omv/modules/py_helper.c b/src/omv/modules/py_helper.c index 9161dfdd3..0ebc8c300 100644 --- a/src/omv/modules/py_helper.c +++ b/src/omv/modules/py_helper.c @@ -37,6 +37,13 @@ image_t *py_helper_arg_to_image_mutable_bayer(const mp_obj_t arg) return arg_img; } +image_t *py_helper_arg_to_image_mutable_bayer_jpeg(const mp_obj_t arg) +{ + image_t *arg_img = py_image_cobj(arg); + PY_ASSERT_TRUE_MSG(IMAGE_IS_MUTABLE_BAYER_JPEG(arg_img), "Image is not mutable!"); + return arg_img; +} + image_t *py_helper_arg_to_image_grayscale(const mp_obj_t arg) { image_t *arg_img = py_image_cobj(arg); diff --git a/src/omv/modules/py_helper.h b/src/omv/modules/py_helper.h index 83d9cd269..10150ff87 100644 --- a/src/omv/modules/py_helper.h +++ b/src/omv/modules/py_helper.h @@ -14,6 +14,7 @@ extern const mp_obj_fun_builtin_var_t py_func_unavailable_obj; image_t *py_helper_arg_to_image_mutable(const mp_obj_t arg); image_t *py_helper_arg_to_image_mutable_bayer(const mp_obj_t arg); +image_t *py_helper_arg_to_image_mutable_bayer_jpeg(const mp_obj_t arg); image_t *py_helper_arg_to_image_grayscale(const mp_obj_t arg); image_t *py_helper_arg_to_image_color(const mp_obj_t arg); image_t *py_helper_keyword_to_image_mutable(uint n_args, const mp_obj_t *args, uint arg_index, diff --git a/src/omv/modules/py_image.c b/src/omv/modules/py_image.c index 201c89db4..c310474b7 100644 --- a/src/omv/modules/py_image.c +++ b/src/omv/modules/py_image.c @@ -870,7 +870,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(py_image_midpoint_pooled_obj, 3, py_image_midp static mp_obj_t py_image_to(int bpp, const uint16_t *default_color_palette, bool copy_to_fb, uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { - image_t *src_img = py_helper_arg_to_image_mutable_bayer(args[0]); + image_t *src_img = py_helper_arg_to_image_mutable_bayer_jpeg(args[0]); float arg_x_scale = 1.f; bool got_x_scale = py_helper_keyword_float_maybe(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_x_scale), &arg_x_scale); @@ -963,6 +963,19 @@ static mp_obj_t py_image_to(int bpp, const uint16_t *default_color_palette, bool IMAGE_HINT_EXTRACT_RGB_CHANNEL_FIRST | IMAGE_HINT_APPLY_COLOR_PALETTE_FIRST); } + } else if (dst_img.bpp >= IMAGE_BPP_JPEG) { + if ((arg_x_scale != 1) || + (arg_y_scale != 1) || + (arg_roi.x != 0) || + (arg_roi.y != 0) || + (arg_roi.w != src_img->w) || + (arg_roi.h != src_img->h) || + (arg_rgb_channel != -1) || + (arg_alpha != 256) || + (color_palette != NULL) || + (alpha_palette != NULL)) { + mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Only jpeg copying is supported!")); + } } if (copy) { @@ -983,11 +996,17 @@ static mp_obj_t py_image_to(int bpp, const uint16_t *default_color_palette, bool dst_img.data = xalloc(image_size(&dst_img)); } - fb_alloc_mark(); - imlib_draw_image(&dst_img, src_img, 0, 0, arg_x_scale, arg_y_scale, &arg_roi, - arg_rgb_channel, arg_alpha, color_palette, alpha_palette, - (hint & (~IMAGE_HINT_CENTER)) | IMAGE_HINT_BLACK_BACKGROUND, NULL, NULL); - fb_alloc_free_till_mark(); + if (dst_img.bpp >= IMAGE_BPP_JPEG) { + if (dst_img.data != src_img->data) { + memcpy(dst_img.data, src_img->data, dst_img.bpp); + } + } else { + fb_alloc_mark(); + imlib_draw_image(&dst_img, src_img, 0, 0, arg_x_scale, arg_y_scale, &arg_roi, + arg_rgb_channel, arg_alpha, color_palette, alpha_palette, + (hint & (~IMAGE_HINT_CENTER)) | IMAGE_HINT_BLACK_BACKGROUND, NULL, NULL); + fb_alloc_free_till_mark(); + } if (arg_other) { arg_other->w = dst_img.w;