mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #2189 from kwagyeman/kwabena/line_op_update
modules/py_image: Update all lineops to use the draw_image backend.
This commit is contained in:
commit
51511ecb10
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
*
|
||||
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
* Copyright (c) 2013-2024 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||
* Copyright (c) 2013-2024 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
*
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
@ -10,7 +10,6 @@
|
||||
*/
|
||||
#include "imlib.h"
|
||||
|
||||
#ifdef IMLIB_ENABLE_BINARY_OPS
|
||||
void imlib_zero_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data) {
|
||||
image_t *mask = data->callback_arg;
|
||||
|
||||
@ -118,6 +117,7 @@ void imlib_mask_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef IMLIB_ENABLE_BINARY_OPS
|
||||
void imlib_binary(image_t *out, image_t *img, list_t *thresholds, bool invert, bool zero, image_t *mask) {
|
||||
image_t bmp;
|
||||
bmp.w = img->w;
|
||||
@ -239,33 +239,40 @@ void imlib_invert(image_t *img) {
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_b_and_line_op(image_t *img, int line, void *other, void *data, bool vflipped) {
|
||||
image_t *mask = (image_t *) data;
|
||||
void imlib_b_and_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data) {
|
||||
image_t *mask = (image_t *) data->callback_arg;
|
||||
|
||||
switch (img->pixfmt) {
|
||||
switch (data->dst_img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
uint32_t *row0 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, line);
|
||||
uint32_t *row1 = (uint32_t *) other;
|
||||
uint32_t *row0 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint32_t *row1 = (uint32_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 32; x += 32) {
|
||||
// Align to 32-bit boundary.
|
||||
for (; (x % 32) && (x < x_end); x++) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 & p1;
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
|
||||
for (; (x_end - x) >= 32; x += 32) {
|
||||
uint32_t p0 = row0[x / 32];
|
||||
uint32_t p1 = ((uint32_t *) row1)[x / 32];
|
||||
row0[x / 32] = p0 & p1;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 & p1;
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 & p1;
|
||||
@ -276,28 +283,27 @@ void imlib_b_and_line_op(image_t *img, int line, void *other, void *data, bool v
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, line);
|
||||
uint8_t *row1 = (uint8_t *) other;
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint8_t *row1 = (uint8_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 4; x += 4) {
|
||||
for (; (x_end - x) >= 4; x += 4) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
*((uint32_t *) (row0 + x)) = p0 & p1;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 & p1;
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 & p1;
|
||||
@ -308,28 +314,27 @@ void imlib_b_and_line_op(image_t *img, int line, void *other, void *data, bool v
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, line);
|
||||
uint16_t *row1 = (uint16_t *) other;
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint16_t *row1 = (uint16_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 2; x += 2) {
|
||||
for (; (x_end - x) >= 2; x += 2) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
*((uint32_t *) (row0 + x)) = p0 & p1;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 & p1;
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 & p1;
|
||||
@ -345,37 +350,40 @@ void imlib_b_and_line_op(image_t *img, int line, void *other, void *data, bool v
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_b_and(image_t *img, const char *path, image_t *other, int scalar, image_t *mask) {
|
||||
imlib_image_operation(img, path, other, scalar, imlib_b_and_line_op, mask);
|
||||
}
|
||||
void imlib_b_nand_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data) {
|
||||
image_t *mask = (image_t *) data->callback_arg;
|
||||
|
||||
static void imlib_b_nand_line_op(image_t *img, int line, void *other, void *data, bool vflipped) {
|
||||
image_t *mask = (image_t *) data;
|
||||
|
||||
switch (img->pixfmt) {
|
||||
switch (data->dst_img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
uint32_t *row0 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, line);
|
||||
uint32_t *row1 = (uint32_t *) other;
|
||||
uint32_t *row0 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint32_t *row1 = (uint32_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 32; x += 32) {
|
||||
// Align to 32-bit boundary.
|
||||
for (; (x % 32) && (x < x_end); x++) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 & p1);
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
|
||||
for (; (x_end - x) >= 32; x += 32) {
|
||||
uint32_t p0 = row0[x / 32];
|
||||
uint32_t p1 = row1[x / 32];
|
||||
row0[x / 32] = ~(p0 & p1);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 & p1);
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 & p1);
|
||||
@ -386,28 +394,27 @@ static void imlib_b_nand_line_op(image_t *img, int line, void *other, void *data
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, line);
|
||||
uint8_t *row1 = (uint8_t *) other;
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint8_t *row1 = (uint8_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 4; x += 4) {
|
||||
for (; (x_end - x) >= 4; x += 4) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
*((uint32_t *) (row0 + x)) = ~(p0 & p1);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 & p1);
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 & p1);
|
||||
@ -418,28 +425,27 @@ static void imlib_b_nand_line_op(image_t *img, int line, void *other, void *data
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, line);
|
||||
uint16_t *row1 = (uint16_t *) other;
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint16_t *row1 = (uint16_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 2; x += 2) {
|
||||
for (; (x_end - x) >= 2; x += 2) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
*((uint32_t *) (row0 + x)) = ~(p0 & p1);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 & p1);
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 & p1);
|
||||
@ -455,37 +461,40 @@ static void imlib_b_nand_line_op(image_t *img, int line, void *other, void *data
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_b_nand(image_t *img, const char *path, image_t *other, int scalar, image_t *mask) {
|
||||
imlib_image_operation(img, path, other, scalar, imlib_b_nand_line_op, mask);
|
||||
}
|
||||
void imlib_b_or_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data) {
|
||||
image_t *mask = (image_t *) data->callback_arg;
|
||||
|
||||
void imlib_b_or_line_op(image_t *img, int line, void *other, void *data, bool vflipped) {
|
||||
image_t *mask = (image_t *) data;
|
||||
|
||||
switch (img->pixfmt) {
|
||||
switch (data->dst_img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
uint32_t *row0 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, line);
|
||||
uint32_t *row1 = (uint32_t *) other;
|
||||
uint32_t *row0 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint32_t *row1 = (uint32_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 32; x += 32) {
|
||||
// Align to 32-bit boundary.
|
||||
for (; (x % 32) && (x < x_end); x++) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 | p1;
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
|
||||
for (; (x_end - x) >= 32; x += 32) {
|
||||
uint32_t p0 = row0[x / 32];
|
||||
uint32_t p1 = row1[x / 32];
|
||||
row0[x / 32] = p0 | p1;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 | p1;
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 | p1;
|
||||
@ -496,28 +505,27 @@ void imlib_b_or_line_op(image_t *img, int line, void *other, void *data, bool vf
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, line);
|
||||
uint8_t *row1 = (uint8_t *) other;
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint8_t *row1 = (uint8_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 4; x += 4) {
|
||||
for (; (x_end - x) >= 4; x += 4) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
*((uint32_t *) (row0 + x)) = p0 | p1;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 | p1;
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 | p1;
|
||||
@ -528,28 +536,27 @@ void imlib_b_or_line_op(image_t *img, int line, void *other, void *data, bool vf
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, line);
|
||||
uint16_t *row1 = (uint16_t *) other;
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint16_t *row1 = (uint16_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 2; x += 2) {
|
||||
for (; (x_end - x) >= 2; x += 2) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
*((uint32_t *) (row0 + x)) = p0 | p1;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 | p1;
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 | p1;
|
||||
@ -565,37 +572,40 @@ void imlib_b_or_line_op(image_t *img, int line, void *other, void *data, bool vf
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_b_or(image_t *img, const char *path, image_t *other, int scalar, image_t *mask) {
|
||||
imlib_image_operation(img, path, other, scalar, imlib_b_or_line_op, mask);
|
||||
}
|
||||
void imlib_b_nor_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data) {
|
||||
image_t *mask = (image_t *) data->callback_arg;
|
||||
|
||||
static void imlib_b_nor_line_op(image_t *img, int line, void *other, void *data, bool vflipped) {
|
||||
image_t *mask = (image_t *) data;
|
||||
|
||||
switch (img->pixfmt) {
|
||||
switch (data->dst_img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
uint32_t *row0 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, line);
|
||||
uint32_t *row1 = (uint32_t *) other;
|
||||
uint32_t *row0 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint32_t *row1 = (uint32_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 32; x += 32) {
|
||||
// Align to 32-bit boundary.
|
||||
for (; (x % 32) && (x < x_end); x++) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 | p1);
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
|
||||
for (; (x_end - x) >= 32; x += 32) {
|
||||
uint32_t p0 = row0[x / 32];
|
||||
uint32_t p1 = row1[x / 32];
|
||||
row0[x / 32] = ~(p0 | p1);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 | p1);
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 | p1);
|
||||
@ -606,28 +616,27 @@ static void imlib_b_nor_line_op(image_t *img, int line, void *other, void *data,
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, line);
|
||||
uint8_t *row1 = (uint8_t *) other;
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint8_t *row1 = (uint8_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 4; x += 4) {
|
||||
for (; (x_end - x) >= 4; x += 4) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
*((uint32_t *) (row0 + x)) = ~(p0 | p1);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 | p1);
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 | p1);
|
||||
@ -638,28 +647,27 @@ static void imlib_b_nor_line_op(image_t *img, int line, void *other, void *data,
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, line);
|
||||
uint16_t *row1 = (uint16_t *) other;
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint16_t *row1 = (uint16_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 2; x += 2) {
|
||||
for (; (x_end - x) >= 2; x += 2) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
*((uint32_t *) (row0 + x)) = ~(p0 | p1);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 | p1);
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 | p1);
|
||||
@ -675,37 +683,40 @@ static void imlib_b_nor_line_op(image_t *img, int line, void *other, void *data,
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_b_nor(image_t *img, const char *path, image_t *other, int scalar, image_t *mask) {
|
||||
imlib_image_operation(img, path, other, scalar, imlib_b_nor_line_op, mask);
|
||||
}
|
||||
void imlib_b_xor_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data) {
|
||||
image_t *mask = (image_t *) data->callback_arg;
|
||||
|
||||
void imlib_b_xor_line_op(image_t *img, int line, void *other, void *data, bool vflipped) {
|
||||
image_t *mask = (image_t *) data;
|
||||
|
||||
switch (img->pixfmt) {
|
||||
switch (data->dst_img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
uint32_t *row0 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, line);
|
||||
uint32_t *row1 = (uint32_t *) other;
|
||||
uint32_t *row0 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint32_t *row1 = (uint32_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 32; x += 32) {
|
||||
// Align to 32-bit boundary.
|
||||
for (; (x % 32) && (x < x_end); x++) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 ^ p1;
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
|
||||
for (; (x_end - x) >= 32; x += 32) {
|
||||
uint32_t p0 = row0[x / 32];
|
||||
uint32_t p1 = row1[x / 32];
|
||||
row0[x / 32] = p0 ^ p1;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 ^ p1;
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 ^ p1;
|
||||
@ -716,28 +727,27 @@ void imlib_b_xor_line_op(image_t *img, int line, void *other, void *data, bool v
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, line);
|
||||
uint8_t *row1 = (uint8_t *) other;
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint8_t *row1 = (uint8_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 4; x += 4) {
|
||||
for (; (x_end - x) >= 4; x += 4) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
*((uint32_t *) (row0 + x)) = p0 ^ p1;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 ^ p1;
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 ^ p1;
|
||||
@ -748,28 +758,27 @@ void imlib_b_xor_line_op(image_t *img, int line, void *other, void *data, bool v
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, line);
|
||||
uint16_t *row1 = (uint16_t *) other;
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint16_t *row1 = (uint16_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 2; x += 2) {
|
||||
for (; (x_end - x) >= 2; x += 2) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
*((uint32_t *) (row0 + x)) = p0 ^ p1;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 ^ p1;
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 ^ p1;
|
||||
@ -785,37 +794,40 @@ void imlib_b_xor_line_op(image_t *img, int line, void *other, void *data, bool v
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_b_xor(image_t *img, const char *path, image_t *other, int scalar, image_t *mask) {
|
||||
imlib_image_operation(img, path, other, scalar, imlib_b_xor_line_op, mask);
|
||||
}
|
||||
void imlib_b_xnor_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data) {
|
||||
image_t *mask = (image_t *) data->callback_arg;
|
||||
|
||||
static void imlib_b_xnor_line_op(image_t *img, int line, void *other, void *data, bool vflipped) {
|
||||
image_t *mask = (image_t *) data;
|
||||
|
||||
switch (img->pixfmt) {
|
||||
switch (data->dst_img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
uint32_t *row0 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, line);
|
||||
uint32_t *row1 = (uint32_t *) other;
|
||||
uint32_t *row0 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint32_t *row1 = (uint32_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 32; x += 32) {
|
||||
// Align to 32-bit boundary.
|
||||
for (; (x % 32) && (x < x_end); x++) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 ^ p1);
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
|
||||
for (; (x_end - x) >= 32; x += 32) {
|
||||
uint32_t p0 = row0[x / 32];
|
||||
uint32_t p1 = row1[x / 32];
|
||||
row0[x / 32] = ~(p0 ^ p1);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 ^ p1);
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 ^ p1);
|
||||
@ -826,28 +838,27 @@ static void imlib_b_xnor_line_op(image_t *img, int line, void *other, void *data
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, line);
|
||||
uint8_t *row1 = (uint8_t *) other;
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint8_t *row1 = (uint8_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 4; x += 4) {
|
||||
for (; (x_end - x) >= 4; x += 4) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
*((uint32_t *) (row0 + x)) = ~(p0 ^ p1);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 ^ p1);
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 ^ p1);
|
||||
@ -858,28 +869,27 @@ static void imlib_b_xnor_line_op(image_t *img, int line, void *other, void *data
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, line);
|
||||
uint16_t *row1 = (uint16_t *) other;
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint16_t *row1 = (uint16_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 2; x += 2) {
|
||||
for (; (x_end - x) >= 2; x += 2) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
*((uint32_t *) (row0 + x)) = ~(p0 ^ p1);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 ^ p1);
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t p = ~(p0 ^ p1);
|
||||
@ -895,10 +905,6 @@ static void imlib_b_xnor_line_op(image_t *img, int line, void *other, void *data
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_b_xnor(image_t *img, const char *path, image_t *other, int scalar, image_t *mask) {
|
||||
imlib_image_operation(img, path, other, scalar, imlib_b_xnor_line_op, mask);
|
||||
}
|
||||
|
||||
static void imlib_erode_dilate(image_t *img, int ksize, int threshold, int e_or_d, image_t *mask) {
|
||||
int brows = ksize + 1;
|
||||
image_t buf;
|
||||
@ -1225,27 +1231,26 @@ void imlib_close(image_t *img, int ksize, int threshold, image_t *mask) {
|
||||
imlib_erode(img, ksize, threshold, mask);
|
||||
}
|
||||
|
||||
void imlib_top_hat(image_t *img, int ksize, int threshold, image_t *mask) {
|
||||
static void imlib_hat(image_t *img, int ksize, int threshold, image_t *mask, binary_morph_op_t op) {
|
||||
image_t temp;
|
||||
temp.w = img->w;
|
||||
temp.h = img->h;
|
||||
temp.pixfmt = img->pixfmt;
|
||||
temp.data = fb_alloc(image_size(img), FB_ALLOC_NO_HINT);
|
||||
temp.data = fb_alloc(image_size(img), FB_ALLOC_CACHE_ALIGN);
|
||||
memcpy(temp.data, img->data, image_size(img));
|
||||
imlib_open(&temp, ksize, threshold, mask);
|
||||
imlib_difference(img, NULL, &temp, 0, mask);
|
||||
fb_free();
|
||||
op(&temp, ksize, threshold, mask);
|
||||
void *dst_row_override = fb_alloc0(image_line_size(img), FB_ALLOC_CACHE_ALIGN);
|
||||
imlib_draw_image(img, &temp, 0, 0, 1.0f, 1.0f, NULL, -1, 256, NULL, NULL, 0,
|
||||
imlib_difference_line_op, mask, dst_row_override);
|
||||
fb_free(); // dst_row_override
|
||||
fb_free(); // temp.data
|
||||
}
|
||||
|
||||
void imlib_top_hat(image_t *img, int ksize, int threshold, image_t *mask) {
|
||||
imlib_hat(img, ksize, threshold, mask, imlib_open);
|
||||
}
|
||||
|
||||
void imlib_black_hat(image_t *img, int ksize, int threshold, image_t *mask) {
|
||||
image_t temp;
|
||||
temp.w = img->w;
|
||||
temp.h = img->h;
|
||||
temp.pixfmt = img->pixfmt;
|
||||
temp.data = fb_alloc(image_size(img), FB_ALLOC_NO_HINT);
|
||||
memcpy(temp.data, img->data, image_size(img));
|
||||
imlib_close(&temp, ksize, threshold, mask);
|
||||
imlib_difference(img, NULL, &temp, 0, mask);
|
||||
fb_free();
|
||||
imlib_hat(img, ksize, threshold, mask, imlib_close);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -606,144 +606,8 @@ bool imlib_read_geometry(FIL *fp, image_t *img, const char *path, img_read_setti
|
||||
imblib_parse_extension(img, path); // Enforce extension!
|
||||
return vflipped;
|
||||
}
|
||||
|
||||
static void imlib_read_pixels(FIL *fp, image_t *img, int n_lines, img_read_settings_t *rs) {
|
||||
switch (rs->format) {
|
||||
case FORMAT_BMP:
|
||||
bmp_read_pixels(fp, img, n_lines, &rs->bmp_rs);
|
||||
break;
|
||||
case FORMAT_PNM:
|
||||
ppm_read_pixels(fp, img, n_lines, &rs->ppm_rs);
|
||||
break;
|
||||
default: // won't happen
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif //IMLIB_ENABLE_IMAGE_FILE_IO
|
||||
|
||||
void imlib_image_operation(image_t *img, const char *path, image_t *other, int scalar, line_op_t op, void *data) {
|
||||
if (path) {
|
||||
#if defined(IMLIB_ENABLE_IMAGE_FILE_IO)
|
||||
uint32_t size = fb_avail() / 2;
|
||||
void *alloc = fb_alloc(size, FB_ALLOC_NO_HINT); // We have to do this before the read.
|
||||
// This code reads a window of an image in at a time and then executes
|
||||
// the line operation on each line in that window before moving to the
|
||||
// next window. The vflipped part is here because BMP files can be saved
|
||||
// vertically flipped resulting in us reading the image backwards.
|
||||
FIL fp;
|
||||
image_t temp;
|
||||
img_read_settings_t rs;
|
||||
bool vflipped = imlib_read_geometry(&fp, &temp, path, &rs);
|
||||
if (!IM_EQUAL(img, &temp)) {
|
||||
file_close(&fp);
|
||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Images not equal!"));
|
||||
}
|
||||
// When processing vertically flipped images the read function will fill
|
||||
// the window up from the bottom. The read function assumes that the
|
||||
// window is equal to an image in size. However, since this is not the
|
||||
// case we shrink the window size to how many lines we're buffering.
|
||||
temp.pixels = alloc;
|
||||
// Set the max buffer height to image height.
|
||||
temp.h = IM_MIN((uint32_t) img->h, (size / (temp.w * temp.bpp)));
|
||||
// This should never happen unless someone forgot to free.
|
||||
if ((!temp.pixels) || (!temp.h)) {
|
||||
mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("Not enough memory available!"));
|
||||
}
|
||||
for (int i = 0; i < img->h; i += temp.h) {
|
||||
// goes past end
|
||||
int lines = IM_MIN(temp.h, img->h - i);
|
||||
imlib_read_pixels(&fp, &temp, lines, &rs);
|
||||
for (int j = 0; j < lines; j++) {
|
||||
if (!vflipped) {
|
||||
op(img, i + j, temp.pixels + (temp.w * temp.bpp * j), data, false);
|
||||
} else {
|
||||
op(img, (img->h - i - lines) + j, temp.pixels + (temp.w * temp.bpp * j), data, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
file_close(&fp);
|
||||
fb_free();
|
||||
#else
|
||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Image I/O is not supported"));
|
||||
#endif
|
||||
} else if (other) {
|
||||
if (!IM_EQUAL(img, other)) {
|
||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Images not equal!"));
|
||||
}
|
||||
switch (img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
for (int i = 0, ii = img->h; i < ii; i++) {
|
||||
op(img, i, IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(other, i), data, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
for (int i = 0, ii = img->h; i < ii; i++) {
|
||||
op(img, i, IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(other, i), data, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
for (int i = 0, ii = img->h; i < ii; i++) {
|
||||
op(img, i, IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(other, i), data, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
uint32_t *row_ptr = fb_alloc(IMAGE_BINARY_LINE_LEN_BYTES(img), FB_ALLOC_NO_HINT);
|
||||
|
||||
for (int i = 0, ii = img->w; i < ii; i++) {
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row_ptr, i, scalar);
|
||||
}
|
||||
|
||||
for (int i = 0, ii = img->h; i < ii; i++) {
|
||||
op(img, i, row_ptr, data, false);
|
||||
}
|
||||
|
||||
fb_free();
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
uint8_t *row_ptr = fb_alloc(IMAGE_GRAYSCALE_LINE_LEN_BYTES(img), FB_ALLOC_NO_HINT);
|
||||
|
||||
for (int i = 0, ii = img->w; i < ii; i++) {
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row_ptr, i, scalar);
|
||||
}
|
||||
|
||||
for (int i = 0, ii = img->h; i < ii; i++) {
|
||||
op(img, i, row_ptr, data, false);
|
||||
}
|
||||
|
||||
fb_free();
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
uint16_t *row_ptr = fb_alloc(IMAGE_RGB565_LINE_LEN_BYTES(img), FB_ALLOC_NO_HINT);
|
||||
|
||||
for (int i = 0, ii = img->w; i < ii; i++) {
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(row_ptr, i, scalar);
|
||||
}
|
||||
|
||||
for (int i = 0, ii = img->h; i < ii; i++) {
|
||||
op(img, i, row_ptr, data, false);
|
||||
}
|
||||
|
||||
fb_free();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(IMLIB_ENABLE_IMAGE_FILE_IO)
|
||||
void imlib_load_image(image_t *img, const char *path) {
|
||||
FIL fp;
|
||||
|
||||
@ -1373,15 +1373,12 @@ void imlib_zero_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data
|
||||
void imlib_mask_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data);
|
||||
void imlib_binary(image_t *out, image_t *img, list_t *thresholds, bool invert, bool zero, image_t *mask);
|
||||
void imlib_invert(image_t *img);
|
||||
void imlib_b_and_line_op(image_t *img, int line, void *other, void *data, bool vflipped);
|
||||
void imlib_b_and(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||||
void imlib_b_nand(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||||
void imlib_b_or_line_op(image_t *img, int line, void *other, void *data, bool vflipped);
|
||||
void imlib_b_or(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||||
void imlib_b_nor(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||||
void imlib_b_xor_line_op(image_t *img, int line, void *other, void *data, bool vflipped);
|
||||
void imlib_b_xor(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||||
void imlib_b_xnor(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||||
void imlib_b_and_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data);
|
||||
void imlib_b_nand_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data);
|
||||
void imlib_b_or_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data);
|
||||
void imlib_b_nor_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data);
|
||||
void imlib_b_xor_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data);
|
||||
void imlib_b_xnor_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data);
|
||||
void imlib_erode(image_t *img, int ksize, int threshold, image_t *mask);
|
||||
void imlib_dilate(image_t *img, int ksize, int threshold, image_t *mask);
|
||||
void imlib_open(image_t *img, int ksize, int threshold, image_t *mask);
|
||||
@ -1389,20 +1386,12 @@ void imlib_close(image_t *img, int ksize, int threshold, image_t *mask);
|
||||
void imlib_top_hat(image_t *img, int ksize, int threshold, image_t *mask);
|
||||
void imlib_black_hat(image_t *img, int ksize, int threshold, image_t *mask);
|
||||
// Math Functions
|
||||
void imlib_replace(image_t *img,
|
||||
const char *path,
|
||||
image_t *other,
|
||||
int scalar,
|
||||
bool hmirror,
|
||||
bool vflip,
|
||||
bool transpose,
|
||||
image_t *mask);
|
||||
void imlib_add(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||||
void imlib_sub(image_t *img, const char *path, image_t *other, int scalar, bool reverse, image_t *mask);
|
||||
void imlib_min(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||||
void imlib_max(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||||
void imlib_difference(image_t *img, const char *path, image_t *other, int scalar, image_t *mask);
|
||||
void imlib_blend(image_t *img, const char *path, image_t *other, int scalar, float alpha, image_t *mask);
|
||||
void imlib_add_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data);
|
||||
void imlib_sub_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data);
|
||||
void imlib_rsub_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data);
|
||||
void imlib_min_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data);
|
||||
void imlib_max_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data);
|
||||
void imlib_difference_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data);
|
||||
// Filtering Functions
|
||||
void imlib_histeq(image_t *img, image_t *mask);
|
||||
void imlib_clahe_histeq(image_t *img, float clip_limit, image_t *mask);
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* This file is part of the OpenMV project.
|
||||
*
|
||||
* Copyright (c) 2013-2021 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||
* Copyright (c) 2013-2021 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
* Copyright (c) 2013-2024 Ibrahim Abdelkader <iabdalkader@openmv.io>
|
||||
* Copyright (c) 2013-2024 Kwabena W. Agyeman <kwagyeman@openmv.io>
|
||||
*
|
||||
* This work is licensed under the MIT license, see the file LICENSE for details.
|
||||
*
|
||||
@ -11,177 +11,36 @@
|
||||
#include "imlib.h"
|
||||
|
||||
#ifdef IMLIB_ENABLE_MATH_OPS
|
||||
typedef struct imlib_replace_line_op_state {
|
||||
bool hmirror, vflip, transpose;
|
||||
image_t *mask;
|
||||
} imlib_replace_line_op_state_t;
|
||||
void imlib_add_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data) {
|
||||
image_t *mask = (image_t *) data->callback_arg;
|
||||
|
||||
static void imlib_replace_line_op(image_t *img, int line, void *other, void *data, bool vflipped) {
|
||||
bool hmirror = ((imlib_replace_line_op_state_t *) data)->hmirror;
|
||||
bool vflip = ((imlib_replace_line_op_state_t *) data)->vflip;
|
||||
bool transpose = ((imlib_replace_line_op_state_t *) data)->transpose;
|
||||
image_t *mask = ((imlib_replace_line_op_state_t *) data)->mask;
|
||||
|
||||
image_t target;
|
||||
memcpy(&target, img, sizeof(image_t));
|
||||
|
||||
if (transpose) {
|
||||
int w = target.w;
|
||||
int h = target.h;
|
||||
target.w = h;
|
||||
target.h = w;
|
||||
}
|
||||
|
||||
switch (img->pixfmt) {
|
||||
switch (data->dst_img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
int v_line = vflip ? (img->h - line - 1) : line;
|
||||
for (int i = 0, j = img->w; i < j; i++) {
|
||||
int h_i = hmirror ? (img->w - i - 1) : i;
|
||||
|
||||
if ((!mask) || image_get_mask_pixel(mask, h_i, v_line)) {
|
||||
int pixel = IMAGE_GET_BINARY_PIXEL_FAST(((uint32_t *) other), h_i);
|
||||
IMAGE_PUT_BINARY_PIXEL(&target, transpose ? v_line : i, transpose ? i : v_line, pixel);
|
||||
}
|
||||
}
|
||||
imlib_b_or_line_op(x, x_end, y_row, data);
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
int v_line = vflip ? (img->h - line - 1) : line;
|
||||
for (int i = 0, j = img->w; i < j; i++) {
|
||||
int h_i = hmirror ? (img->w - i - 1) : i;
|
||||
|
||||
if ((!mask) || image_get_mask_pixel(mask, h_i, v_line)) {
|
||||
int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(((uint8_t *) other), h_i);
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL(&target, transpose ? v_line : i, transpose ? i : v_line, pixel);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
int v_line = vflip ? (img->h - line - 1) : line;
|
||||
for (int i = 0, j = img->w; i < j; i++) {
|
||||
int h_i = hmirror ? (img->w - i - 1) : i;
|
||||
|
||||
if ((!mask) || image_get_mask_pixel(mask, h_i, v_line)) {
|
||||
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(((uint16_t *) other), h_i);
|
||||
IMAGE_PUT_RGB565_PIXEL(&target, transpose ? v_line : i, transpose ? i : v_line, pixel);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_replace(image_t *img,
|
||||
const char *path,
|
||||
image_t *other,
|
||||
int scalar,
|
||||
bool hmirror,
|
||||
bool vflip,
|
||||
bool transpose,
|
||||
image_t *mask) {
|
||||
bool in_place = img->data == other->data;
|
||||
image_t temp;
|
||||
|
||||
if (in_place) {
|
||||
memcpy(&temp, other, sizeof(image_t));
|
||||
temp.data = fb_alloc(image_size(&temp), FB_ALLOC_NO_HINT);
|
||||
memcpy(temp.data, other->data, image_size(&temp));
|
||||
other = &temp;
|
||||
}
|
||||
|
||||
// To improve transpose performance we will split the operation up into chunks that fit in
|
||||
// onchip RAM. These chunks will then be copied to the target buffer in an efficent manner.
|
||||
if (path == NULL && other && transpose) {
|
||||
uint32_t size;
|
||||
void *data = fb_alloc_all(&size, FB_ALLOC_PREFER_SPEED);
|
||||
// line_num stores how many lines we can do at a time with on-chip RAM.
|
||||
int line_num = size / image_line_size(other);
|
||||
// Transposed chunks will be copied to the output image...
|
||||
uint8_t *img_data = img->data;
|
||||
int t_line_size = (image_line_size(img) * img->h) / img->w;
|
||||
// Work top to bottom transposing as many lines at a time in a chunk of the image.
|
||||
for (int i = 0, ii = other->h; i < ii; i += line_num) {
|
||||
line_num = IM_MIN(line_num, (ii - i));
|
||||
// Make an image that is a slice of the input image.
|
||||
image_t in = {.w = other->w, .h = line_num, .pixfmt = other->pixfmt};
|
||||
in.data = other->data + (image_line_size(other) * i);
|
||||
// Make an image that will hold the transposed output.
|
||||
image_t out = in;
|
||||
out.data = data;
|
||||
// Transpose the slice of the input image.
|
||||
imlib_replace_line_op_state_t state;
|
||||
state.hmirror = hmirror;
|
||||
state.vflip = vflip;
|
||||
state.mask = mask;
|
||||
state.transpose = true;
|
||||
imlib_image_operation(&out, NULL, &in, 0, imlib_replace_line_op, &state);
|
||||
out.w = line_num;
|
||||
out.h = other->w;
|
||||
// Copy lines of the chunk to the target image.
|
||||
int out_line_size = image_line_size(&out);
|
||||
for (int j = 0, jj = out.h; j < jj; j++) {
|
||||
memcpy(img_data + (t_line_size * j), out.data + (out_line_size * j), out_line_size);
|
||||
}
|
||||
// Slide the offset for the first line over by the size of the slice we transposed.
|
||||
img_data += out_line_size;
|
||||
}
|
||||
fb_free(); // fb_alloc_all
|
||||
} else {
|
||||
imlib_replace_line_op_state_t state;
|
||||
state.hmirror = hmirror;
|
||||
state.vflip = vflip;
|
||||
state.mask = mask;
|
||||
state.transpose = transpose;
|
||||
imlib_image_operation(img, path, other, scalar, imlib_replace_line_op, &state);
|
||||
}
|
||||
|
||||
if (in_place) {
|
||||
fb_free();
|
||||
}
|
||||
|
||||
if (transpose) {
|
||||
int w = img->w;
|
||||
int h = img->h;
|
||||
img->w = h;
|
||||
img->h = w;
|
||||
}
|
||||
}
|
||||
|
||||
static void imlib_add_line_op(image_t *img, int line, void *other, void *data, bool vflipped) {
|
||||
image_t *mask = (image_t *) data;
|
||||
|
||||
switch (img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
imlib_b_or_line_op(img, line, other, data, vflipped);
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, line);
|
||||
uint8_t *row1 = (uint8_t *) other;
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint8_t *row1 = (uint8_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if defined(ARM_MATH_DSP)
|
||||
for (; (img->w - x) >= 4; x += 4) {
|
||||
for (; (x_end - x) >= 4; x += 4) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
*((uint32_t *) (row0 + x)) = __UQADD8(p0, p1);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = __USAT(p0 + p1, 8);
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = __USAT(p0 + p1, 8);
|
||||
@ -192,13 +51,12 @@ static void imlib_add_line_op(image_t *img, int line, void *other, void *data, b
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, line);
|
||||
uint16_t *row1 = (uint16_t *) other;
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint16_t *row1 = (uint16_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if defined(ARM_MATH_DSP)
|
||||
for (; (img->w - x) >= 2; x += 2) {
|
||||
for (; (x_end - x) >= 2; x += 2) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
uint32_t r = __USAT16(((p0 >> 11) & 0x1f001f) + ((p1 >> 11) & 0x1f001f), 5);
|
||||
@ -208,7 +66,7 @@ static void imlib_add_line_op(image_t *img, int line, void *other, void *data, b
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t r = __USAT(COLOR_RGB565_TO_R5(p0) + COLOR_RGB565_TO_R5(p1), 5);
|
||||
@ -217,8 +75,8 @@ static void imlib_add_line_op(image_t *img, int line, void *other, void *data, b
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(row0, x, COLOR_R5_G6_B5_TO_RGB565(r, g, b));
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t r = __USAT(COLOR_RGB565_TO_R5(p0) + COLOR_RGB565_TO_R5(p1), 5);
|
||||
@ -236,37 +94,40 @@ static void imlib_add_line_op(image_t *img, int line, void *other, void *data, b
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_add(image_t *img, const char *path, image_t *other, int scalar, image_t *mask) {
|
||||
imlib_image_operation(img, path, other, scalar, imlib_add_line_op, mask);
|
||||
}
|
||||
void imlib_sub_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data) {
|
||||
image_t *mask = (image_t *) data->callback_arg;
|
||||
|
||||
static void imlib_sub_line_op(image_t *img, int line, void *other, void *data, bool vflipped) {
|
||||
image_t *mask = (image_t *) data;
|
||||
|
||||
switch (img->pixfmt) {
|
||||
switch (data->dst_img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
uint32_t *row0 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, line);
|
||||
uint32_t *row1 = (uint32_t *) other;
|
||||
uint32_t *row0 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint32_t *row1 = (uint32_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 32; x += 32) {
|
||||
// Align to 32-bit boundary.
|
||||
for (; (x % 32) && (x < x_end); x++) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 > p1;
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
|
||||
for (; (x_end - x) >= 32; x += 32) {
|
||||
uint32_t p0 = row0[x / 32];
|
||||
uint32_t p1 = row1[x / 32];
|
||||
row0[x / 32] = p0 & (~p1); // the same as p0 > p1 for all bits
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 > p1;
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p0 > p1;
|
||||
@ -277,28 +138,27 @@ static void imlib_sub_line_op(image_t *img, int line, void *other, void *data, b
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, line);
|
||||
uint8_t *row1 = (uint8_t *) other;
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint8_t *row1 = (uint8_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if defined(ARM_MATH_DSP)
|
||||
for (; (img->w - x) >= 4; x += 4) {
|
||||
for (; (x_end - x) >= 4; x += 4) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
*((uint32_t *) (row0 + x)) = __UQSUB8(p0, p1);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = __USAT((int32_t) (p0 - p1), 8);
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = __USAT((int32_t) (p0 - p1), 8);
|
||||
@ -309,13 +169,12 @@ static void imlib_sub_line_op(image_t *img, int line, void *other, void *data, b
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, line);
|
||||
uint16_t *row1 = (uint16_t *) other;
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint16_t *row1 = (uint16_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if defined(ARM_MATH_DSP)
|
||||
for (; (img->w - x) >= 2; x += 2) {
|
||||
for (; (x_end - x) >= 2; x += 2) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
uint32_t r = __USAT16(__SSUB16((p0 >> 11) & 0x1f001f, (p1 >> 11) & 0x1f001f), 5);
|
||||
@ -325,7 +184,7 @@ static void imlib_sub_line_op(image_t *img, int line, void *other, void *data, b
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t r = __USAT((int32_t) (COLOR_RGB565_TO_R5(p0) - COLOR_RGB565_TO_R5(p1)), 5);
|
||||
@ -334,8 +193,8 @@ static void imlib_sub_line_op(image_t *img, int line, void *other, void *data, b
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(row0, x, COLOR_R5_G6_B5_TO_RGB565(r, g, b));
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t r = __USAT((int32_t) (COLOR_RGB565_TO_R5(p0) - COLOR_RGB565_TO_R5(p1)), 5);
|
||||
@ -353,33 +212,40 @@ static void imlib_sub_line_op(image_t *img, int line, void *other, void *data, b
|
||||
}
|
||||
}
|
||||
|
||||
static void imlib_rsub_line_op(image_t *img, int line, void *other, void *data, bool vflipped) {
|
||||
image_t *mask = (image_t *) data;
|
||||
void imlib_rsub_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data) {
|
||||
image_t *mask = (image_t *) data->callback_arg;
|
||||
|
||||
switch (img->pixfmt) {
|
||||
switch (data->dst_img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
uint32_t *row0 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, line);
|
||||
uint32_t *row1 = (uint32_t *) other;
|
||||
uint32_t *row0 = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint32_t *row1 = (uint32_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if (__ARM_ARCH > 6)
|
||||
for (; (img->w - x) >= 32; x += 32) {
|
||||
// Align to 32-bit boundary.
|
||||
for (; (x % 32) && (x < x_end); x++) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p1 > p0;
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
|
||||
for (; (x_end - x) >= 32; x += 32) {
|
||||
uint32_t p0 = row0[x / 32];
|
||||
uint32_t p1 = row1[x / 32];
|
||||
row0[x / 32] = p1 & (~p0); // the same as p1 > p0 for all bits
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p1 > p0;
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_BINARY_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_BINARY_PIXEL_FAST(row1, x);
|
||||
uint32_t p = p1 > p0;
|
||||
@ -390,28 +256,27 @@ static void imlib_rsub_line_op(image_t *img, int line, void *other, void *data,
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, line);
|
||||
uint8_t *row1 = (uint8_t *) other;
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint8_t *row1 = (uint8_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if defined(ARM_MATH_DSP)
|
||||
for (; (img->w - x) >= 4; x += 4) {
|
||||
for (; (x_end - x) >= 4; x += 4) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
*((uint32_t *) (row0 + x)) = __UQSUB8(p1, p0);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = __USAT((int32_t) (p1 - p0), 8);
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = __USAT((int32_t) (p1 - p0), 8);
|
||||
@ -422,13 +287,12 @@ static void imlib_rsub_line_op(image_t *img, int line, void *other, void *data,
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, line);
|
||||
uint16_t *row1 = (uint16_t *) other;
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint16_t *row1 = (uint16_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if defined(ARM_MATH_DSP)
|
||||
for (; (img->w - x) >= 2; x += 2) {
|
||||
for (; (x_end - x) >= 2; x += 2) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
uint32_t r = __USAT16(__SSUB16((p1 >> 11) & 0x1f001f, (p0 >> 11) & 0x1f001f), 5);
|
||||
@ -438,7 +302,7 @@ static void imlib_rsub_line_op(image_t *img, int line, void *other, void *data,
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t r = __USAT((int32_t) (COLOR_RGB565_TO_R5(p1) - COLOR_RGB565_TO_R5(p0)), 5);
|
||||
@ -447,8 +311,8 @@ static void imlib_rsub_line_op(image_t *img, int line, void *other, void *data,
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(row0, x, COLOR_R5_G6_B5_TO_RGB565(r, g, b));
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t r = __USAT((int32_t) (COLOR_RGB565_TO_R5(p1) - COLOR_RGB565_TO_R5(p0)), 5);
|
||||
@ -466,25 +330,20 @@ static void imlib_rsub_line_op(image_t *img, int line, void *other, void *data,
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_sub(image_t *img, const char *path, image_t *other, int scalar, bool reverse, image_t *mask) {
|
||||
imlib_image_operation(img, path, other, scalar, reverse ? imlib_rsub_line_op : imlib_sub_line_op, mask);
|
||||
}
|
||||
void imlib_min_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data) {
|
||||
image_t *mask = (image_t *) data->callback_arg;
|
||||
|
||||
static void imlib_min_line_op(image_t *img, int line, void *other, void *data, bool vflipped) {
|
||||
image_t *mask = (image_t *) data;
|
||||
|
||||
switch (img->pixfmt) {
|
||||
switch (data->dst_img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
imlib_b_and_line_op(img, line, other, data, vflipped);
|
||||
imlib_b_and_line_op(x, x_end, y_row, data);
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, line);
|
||||
uint8_t *row1 = (uint8_t *) other;
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint8_t *row1 = (uint8_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if defined(ARM_MATH_DSP)
|
||||
for (; (img->w - x) >= 4; x += 4) {
|
||||
for (; (x_end - x) >= 4; x += 4) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
__USUB8(p0, p1);
|
||||
@ -492,15 +351,15 @@ static void imlib_min_line_op(image_t *img, int line, void *other, void *data, b
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = IM_MIN(p0, p1);
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = IM_MIN(p0, p1);
|
||||
@ -511,13 +370,12 @@ static void imlib_min_line_op(image_t *img, int line, void *other, void *data, b
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, line);
|
||||
uint16_t *row1 = (uint16_t *) other;
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint16_t *row1 = (uint16_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if defined(ARM_MATH_DSP)
|
||||
for (; (img->w - x) >= 2; x += 2) {
|
||||
for (; (x_end - x) >= 2; x += 2) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
uint32_t p0_rb = p0 & 0xf81ff81f, p1_rb = p1 & 0xf81ff81f;
|
||||
@ -530,7 +388,7 @@ static void imlib_min_line_op(image_t *img, int line, void *other, void *data, b
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t r = IM_MIN(COLOR_RGB565_TO_R5(p0), COLOR_RGB565_TO_R5(p1));
|
||||
@ -539,8 +397,8 @@ static void imlib_min_line_op(image_t *img, int line, void *other, void *data, b
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(row0, x, COLOR_R5_G6_B5_TO_RGB565(r, g, b));
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t r = IM_MIN(COLOR_RGB565_TO_R5(p0), COLOR_RGB565_TO_R5(p1));
|
||||
@ -558,26 +416,21 @@ static void imlib_min_line_op(image_t *img, int line, void *other, void *data, b
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_min(image_t *img, const char *path, image_t *other, int scalar, image_t *mask) {
|
||||
imlib_image_operation(img, path, other, scalar, imlib_min_line_op, mask);
|
||||
}
|
||||
void imlib_max_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data) {
|
||||
image_t *mask = (image_t *) data->callback_arg;
|
||||
|
||||
static void imlib_max_line_op(image_t *img, int line, void *other, void *data, bool vflipped) {
|
||||
image_t *mask = (image_t *) data;
|
||||
|
||||
switch (img->pixfmt) {
|
||||
switch (data->dst_img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
imlib_b_or_line_op(img, line, other, data, vflipped);
|
||||
imlib_b_or_line_op(x, x_end, y_row, data);
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, line);
|
||||
uint8_t *row1 = (uint8_t *) other;
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint8_t *row1 = (uint8_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if defined(ARM_MATH_DSP)
|
||||
for (; (img->w - x) >= 4; x += 4) {
|
||||
for (; (x_end - x) >= 4; x += 4) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
__USUB8(p0, p1);
|
||||
@ -585,15 +438,15 @@ static void imlib_max_line_op(image_t *img, int line, void *other, void *data, b
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = IM_MAX(p0, p1);
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = IM_MAX(p0, p1);
|
||||
@ -604,13 +457,12 @@ static void imlib_max_line_op(image_t *img, int line, void *other, void *data, b
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, line);
|
||||
uint16_t *row1 = (uint16_t *) other;
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint16_t *row1 = (uint16_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if defined(ARM_MATH_DSP)
|
||||
for (; (img->w - x) >= 2; x += 2) {
|
||||
for (; (x_end - x) >= 2; x += 2) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
uint32_t p0_rb = p0 & 0xf81ff81f, p1_rb = p1 & 0xf81ff81f;
|
||||
@ -623,7 +475,7 @@ static void imlib_max_line_op(image_t *img, int line, void *other, void *data, b
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t r = IM_MAX(COLOR_RGB565_TO_R5(p0), COLOR_RGB565_TO_R5(p1));
|
||||
@ -632,8 +484,8 @@ static void imlib_max_line_op(image_t *img, int line, void *other, void *data, b
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(row0, x, COLOR_R5_G6_B5_TO_RGB565(r, g, b));
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t r = IM_MAX(COLOR_RGB565_TO_R5(p0), COLOR_RGB565_TO_R5(p1));
|
||||
@ -651,26 +503,21 @@ static void imlib_max_line_op(image_t *img, int line, void *other, void *data, b
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_max(image_t *img, const char *path, image_t *other, int scalar, image_t *mask) {
|
||||
imlib_image_operation(img, path, other, scalar, imlib_max_line_op, mask);
|
||||
}
|
||||
void imlib_difference_line_op(int x, int x_end, int y_row, imlib_draw_row_data_t *data) {
|
||||
image_t *mask = (image_t *) data->callback_arg;
|
||||
|
||||
static void imlib_difference_line_op(image_t *img, int line, void *other, void *data, bool vflipped) {
|
||||
image_t *mask = (image_t *) data;
|
||||
|
||||
switch (img->pixfmt) {
|
||||
switch (data->dst_img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
imlib_b_xor_line_op(img, line, other, data, vflipped);
|
||||
imlib_b_xor_line_op(x, x_end, y_row, data);
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, line);
|
||||
uint8_t *row1 = (uint8_t *) other;
|
||||
uint8_t *row0 = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint8_t *row1 = (uint8_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if defined(ARM_MATH_DSP)
|
||||
for (; (img->w - x) >= 4; x += 4) {
|
||||
for (; (x_end - x) >= 4; x += 4) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
uint32_t sub0 = __USUB8(p0, p1);
|
||||
@ -679,15 +526,15 @@ static void imlib_difference_line_op(image_t *img, int line, void *other, void *
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = __USAD8(p0, p1);
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(row0, x, p);
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_GRAYSCALE_PIXEL_FAST(row1, x);
|
||||
uint32_t p = __USAD8(p0, p1);
|
||||
@ -698,13 +545,12 @@ static void imlib_difference_line_op(image_t *img, int line, void *other, void *
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, line);
|
||||
uint16_t *row1 = (uint16_t *) other;
|
||||
uint16_t *row0 = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(data->dst_img, y_row);
|
||||
uint16_t *row1 = (uint16_t *) data->dst_row_override;
|
||||
|
||||
if (!mask) {
|
||||
size_t x = 0;
|
||||
#if defined(ARM_MATH_DSP)
|
||||
for (; (img->w - x) >= 2; x += 2) {
|
||||
for (; (x_end - x) >= 2; x += 2) {
|
||||
uint32_t p0 = *((uint32_t *) (row0 + x));
|
||||
uint32_t p1 = *((uint32_t *) (row1 + x));
|
||||
uint32_t p0_rb = p0 & 0xf81ff81f, p1_rb = p1 & 0xf81ff81f;
|
||||
@ -719,7 +565,7 @@ static void imlib_difference_line_op(image_t *img, int line, void *other, void *
|
||||
}
|
||||
#endif
|
||||
|
||||
for (; x < img->w; x++) {
|
||||
for (; x < x_end; x++) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t r = __USAD8(COLOR_RGB565_TO_R5(p0), COLOR_RGB565_TO_R5(p1));
|
||||
@ -728,8 +574,8 @@ static void imlib_difference_line_op(image_t *img, int line, void *other, void *
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(row0, x, COLOR_R5_G6_B5_TO_RGB565(r, g, b));
|
||||
}
|
||||
} else {
|
||||
for (size_t x = 0; x < img->w; x++) {
|
||||
if (image_get_mask_pixel(mask, x, line)) {
|
||||
for (; x < x_end; x++) {
|
||||
if (image_get_mask_pixel(mask, x, y_row)) {
|
||||
uint32_t p0 = IMAGE_GET_RGB565_PIXEL_FAST(row0, x);
|
||||
uint32_t p1 = IMAGE_GET_RGB565_PIXEL_FAST(row1, x);
|
||||
uint32_t r = __USAD8(COLOR_RGB565_TO_R5(p0), COLOR_RGB565_TO_R5(p1));
|
||||
@ -746,69 +592,4 @@ static void imlib_difference_line_op(image_t *img, int line, void *other, void *
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_difference(image_t *img, const char *path, image_t *other, int scalar, image_t *mask) {
|
||||
imlib_image_operation(img, path, other, scalar, imlib_difference_line_op, mask);
|
||||
}
|
||||
|
||||
typedef struct imlib_blend_line_op_state {
|
||||
float alpha;
|
||||
image_t *mask;
|
||||
} imlib_blend_line_op_t;
|
||||
|
||||
static void imlib_blend_line_op(image_t *img, int line, void *other, void *data, bool vflipped) {
|
||||
float alpha = ((imlib_blend_line_op_t *) data)->alpha, beta = 1 - alpha;
|
||||
image_t *mask = ((imlib_blend_line_op_t *) data)->mask;
|
||||
|
||||
switch (img->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
uint32_t *data = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, line);
|
||||
for (int i = 0, j = img->w; i < j; i++) {
|
||||
if ((!mask) || image_get_mask_pixel(mask, i, line)) {
|
||||
int dataPixel = IMAGE_GET_BINARY_PIXEL_FAST(data, i);
|
||||
int otherPixel = IMAGE_GET_BINARY_PIXEL_FAST(((uint32_t *) other), i);
|
||||
int p = (dataPixel * alpha) + (otherPixel * beta);
|
||||
IMAGE_PUT_BINARY_PIXEL_FAST(data, i, p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
uint8_t *data = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, line);
|
||||
for (int i = 0, j = img->w; i < j; i++) {
|
||||
if ((!mask) || image_get_mask_pixel(mask, i, line)) {
|
||||
int dataPixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(data, i);
|
||||
int otherPixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(((uint8_t *) other), i);
|
||||
int p = (dataPixel * alpha) + (otherPixel * beta);
|
||||
IMAGE_PUT_GRAYSCALE_PIXEL_FAST(data, i, p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
uint16_t *data = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, line);
|
||||
for (int i = 0, j = img->w; i < j; i++) {
|
||||
if ((!mask) || image_get_mask_pixel(mask, i, line)) {
|
||||
int dataPixel = IMAGE_GET_RGB565_PIXEL_FAST(data, i);
|
||||
int otherPixel = IMAGE_GET_RGB565_PIXEL_FAST(((uint16_t *) other), i);
|
||||
int r = (COLOR_RGB565_TO_R5(dataPixel) * alpha) + (COLOR_RGB565_TO_R5(otherPixel) * beta);
|
||||
int g = (COLOR_RGB565_TO_G6(dataPixel) * alpha) + (COLOR_RGB565_TO_G6(otherPixel) * beta);
|
||||
int b = (COLOR_RGB565_TO_B5(dataPixel) * alpha) + (COLOR_RGB565_TO_B5(otherPixel) * beta);
|
||||
IMAGE_PUT_RGB565_PIXEL_FAST(data, i, COLOR_R5_G6_B5_TO_RGB565(r, g, b));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void imlib_blend(image_t *img, const char *path, image_t *other, int scalar, float alpha, image_t *mask) {
|
||||
imlib_blend_line_op_t state;
|
||||
state.alpha = alpha;
|
||||
state.mask = mask;
|
||||
imlib_image_operation(img, path, other, scalar, imlib_blend_line_op, &state);
|
||||
}
|
||||
#endif //IMLIB_ENABLE_MATH_OPS
|
||||
#endif // IMLIB_ENABLE_MATH_OPS
|
||||
|
||||
@ -1491,94 +1491,6 @@ static mp_obj_t py_image_draw_edges(uint n_args, const mp_obj_t *args, mp_map_t
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_draw_edges_obj, 2, py_image_draw_edges);
|
||||
|
||||
static mp_obj_t py_image_draw_image(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
fb_alloc_mark();
|
||||
image_t *arg_img = py_helper_arg_to_image(args[0], ARG_IMAGE_MUTABLE);
|
||||
image_t *arg_other = py_helper_arg_to_image(args[1], ARG_IMAGE_ANY | ARG_IMAGE_ALLOC);
|
||||
|
||||
const mp_obj_t *arg_vec;
|
||||
uint offset = py_helper_consume_array(n_args, args, 2, 2, &arg_vec);
|
||||
int arg_x_off = mp_obj_get_int(arg_vec[0]);
|
||||
int arg_y_off = mp_obj_get_int(arg_vec[1]);
|
||||
|
||||
float arg_x_scale = 1.f;
|
||||
bool got_x_scale = py_helper_keyword_float_maybe(n_args,
|
||||
args,
|
||||
offset + 0,
|
||||
kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_x_scale),
|
||||
&arg_x_scale);
|
||||
|
||||
float arg_y_scale = 1.f;
|
||||
bool got_y_scale = py_helper_keyword_float_maybe(n_args,
|
||||
args,
|
||||
offset + 1,
|
||||
kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_y_scale),
|
||||
&arg_y_scale);
|
||||
|
||||
rectangle_t arg_roi;
|
||||
py_helper_keyword_rectangle_roi(arg_other, n_args, args, offset + 2, kw_args, &arg_roi);
|
||||
|
||||
int arg_rgb_channel = py_helper_keyword_int(n_args, args, offset + 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_rgb_channel), -1);
|
||||
if ((arg_rgb_channel < -1) || (2 < arg_rgb_channel)) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("-1 <= rgb_channel <= 2!"));
|
||||
}
|
||||
|
||||
int arg_alpha = py_helper_keyword_int(n_args, args, offset + 4, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_alpha), 256);
|
||||
if ((arg_alpha < 0) || (256 < arg_alpha)) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("0 <= alpha <= 256!"));
|
||||
}
|
||||
|
||||
const uint16_t *color_palette = py_helper_keyword_color_palette(n_args, args, offset + 5, kw_args, NULL);
|
||||
const uint8_t *alpha_palette = py_helper_keyword_alpha_palette(n_args, args, offset + 6, kw_args, NULL);
|
||||
|
||||
image_hint_t hint = py_helper_keyword_int(n_args, args, offset + 7, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_hint), 0);
|
||||
|
||||
float arg_x_size;
|
||||
bool got_x_size = py_helper_keyword_float_maybe(n_args,
|
||||
args,
|
||||
offset + 8,
|
||||
kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_x_size),
|
||||
&arg_x_size);
|
||||
|
||||
float arg_y_size;
|
||||
bool got_y_size = py_helper_keyword_float_maybe(n_args,
|
||||
args,
|
||||
offset + 9,
|
||||
kw_args,
|
||||
MP_OBJ_NEW_QSTR(MP_QSTR_y_size),
|
||||
&arg_y_size);
|
||||
|
||||
if (got_x_scale && got_x_size) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Choose either x_scale or x_size not both!"));
|
||||
}
|
||||
if (got_y_scale && got_y_size) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Choose either y_scale or y_size not both!"));
|
||||
}
|
||||
|
||||
if (got_x_size) {
|
||||
arg_x_scale = arg_x_size / arg_roi.w;
|
||||
}
|
||||
if (got_y_size) {
|
||||
arg_y_scale = arg_y_size / arg_roi.h;
|
||||
}
|
||||
|
||||
if ((!got_x_scale) && (!got_x_size) && got_y_size) {
|
||||
arg_x_scale = arg_y_scale;
|
||||
}
|
||||
if ((!got_y_scale) && (!got_y_size) && got_x_size) {
|
||||
arg_y_scale = arg_x_scale;
|
||||
}
|
||||
|
||||
imlib_draw_image(arg_img, arg_other, arg_x_off, arg_y_off, arg_x_scale, arg_y_scale, &arg_roi,
|
||||
arg_rgb_channel, arg_alpha, color_palette, alpha_palette, hint, NULL, NULL, NULL);
|
||||
fb_alloc_free_till_mark();
|
||||
return args[0];
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_draw_image_obj, 3, py_image_draw_image);
|
||||
|
||||
static mp_obj_t py_image_draw_keypoints(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
image_t *arg_img = py_helper_arg_to_image(args[0], ARG_IMAGE_MUTABLE);
|
||||
|
||||
@ -1772,6 +1684,115 @@ static mp_obj_t py_image_flood_fill(uint n_args, const mp_obj_t *args, mp_map_t
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_flood_fill_obj, 2, py_image_flood_fill);
|
||||
#endif // IMLIB_ENABLE_FLOOD_FILL
|
||||
|
||||
static mp_obj_t py_image_line_op(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args,
|
||||
imlib_draw_row_callback_t callback) {
|
||||
enum {
|
||||
ARG_image, ARG_x, ARG_y, ARG_x_scale, ARG_y_scale, ARG_roi,
|
||||
ARG_channel, ARG_alpha, ARG_color_palette, ARG_alpha_palette, ARG_hint, ARG_mask
|
||||
};
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_image, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = MP_ROM_NONE} },
|
||||
{ MP_QSTR_x, MP_ARG_INT, {.u_int = 0 } },
|
||||
{ MP_QSTR_y, MP_ARG_INT, {.u_int = 0 } },
|
||||
{ MP_QSTR_x_scale, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
{ MP_QSTR_y_scale, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
{ MP_QSTR_roi, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
{ MP_QSTR_rgb_channel, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = -1 } },
|
||||
{ MP_QSTR_alpha, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 256 } },
|
||||
{ MP_QSTR_color_palette, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
{ MP_QSTR_alpha_palette, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
{ MP_QSTR_hint, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0 } },
|
||||
{ MP_QSTR_mask, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_rom_obj = MP_ROM_NONE} },
|
||||
};
|
||||
|
||||
// Parse args.
|
||||
image_t *image = py_helper_arg_to_image(pos_args[0], ARG_IMAGE_MUTABLE);
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
fb_alloc_mark();
|
||||
uint32_t data;
|
||||
image_t temp = {.w = 1, .h = 1, .pixfmt = image->pixfmt, .data = (uint8_t *) &data}, *other = &temp;
|
||||
|
||||
// Handle passing a scalar as an image.
|
||||
if (mp_obj_is_integer(args[ARG_image].u_obj)) {
|
||||
data = mp_obj_get_int(args[ARG_image].u_obj);
|
||||
args[ARG_hint].u_int |= IMAGE_HINT_SCALE_ASPECT_IGNORE;
|
||||
// Handle passing a rgb888 value as an image.
|
||||
} else if (MP_OBJ_IS_TYPE(args[ARG_image].u_obj, &mp_type_tuple) ||
|
||||
MP_OBJ_IS_TYPE(args[ARG_image].u_obj, &mp_type_list)) {
|
||||
mp_obj_t *rgb888;
|
||||
mp_obj_get_array_fixed_n(args[ARG_image].u_obj, 3, &rgb888);
|
||||
int r = IM_CLAMP(mp_obj_get_int(rgb888[0]), COLOR_R8_MIN, COLOR_R8_MAX);
|
||||
int g = IM_CLAMP(mp_obj_get_int(rgb888[1]), COLOR_G8_MIN, COLOR_G8_MAX);
|
||||
int b = IM_CLAMP(mp_obj_get_int(rgb888[2]), COLOR_B8_MIN, COLOR_B8_MAX);
|
||||
switch (image->pixfmt) {
|
||||
case PIXFORMAT_BINARY: {
|
||||
data = COLOR_RGB888_TO_Y(r, g, b) > 127;
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_GRAYSCALE: {
|
||||
data = COLOR_RGB888_TO_Y(r, g, b);
|
||||
break;
|
||||
}
|
||||
case PIXFORMAT_RGB565: {
|
||||
data = COLOR_R8_G8_B8_TO_RGB565(r, g, b);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
args[ARG_hint].u_int |= IMAGE_HINT_SCALE_ASPECT_IGNORE;
|
||||
} else {
|
||||
other = py_helper_arg_to_image(args[ARG_image].u_obj, ARG_IMAGE_ANY | ARG_IMAGE_ALLOC);
|
||||
}
|
||||
|
||||
rectangle_t roi = py_helper_arg_to_roi(args[ARG_roi].u_obj, other);
|
||||
|
||||
if (args[ARG_channel].u_int < -1 || args[ARG_channel].u_int > 2) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("RGB channel can be 0, 1, or 2"));
|
||||
}
|
||||
|
||||
if (args[ARG_alpha].u_int < 0 || args[ARG_alpha].u_int > 256) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Alpha ranges between 0 and 256"));
|
||||
}
|
||||
|
||||
float x_scale = 1.0f;
|
||||
float y_scale = 1.0f;
|
||||
py_helper_arg_to_scale(args[ARG_x_scale].u_obj, args[ARG_y_scale].u_obj, &x_scale, &y_scale);
|
||||
|
||||
const uint16_t *color_palette = py_helper_arg_to_palette(args[ARG_color_palette].u_obj, PIXFORMAT_RGB565);
|
||||
const uint8_t *alpha_palette = py_helper_arg_to_palette(args[ARG_alpha_palette].u_obj, PIXFORMAT_GRAYSCALE);
|
||||
|
||||
image_t *mask = NULL;
|
||||
if (args[ARG_mask].u_obj != mp_const_none) {
|
||||
mask = py_helper_arg_to_image(args[ARG_mask].u_obj, ARG_IMAGE_MUTABLE | ARG_IMAGE_ALLOC);
|
||||
}
|
||||
|
||||
if ((!callback) && mask) {
|
||||
callback = imlib_mask_line_op;
|
||||
}
|
||||
|
||||
void *dst_row_override = NULL;
|
||||
if (callback) {
|
||||
dst_row_override = fb_alloc0(image_line_size(image), FB_ALLOC_CACHE_ALIGN);
|
||||
// Necessary for alpha blending to work correctly.
|
||||
args[ARG_hint].u_int |= IMAGE_HINT_BLACK_BACKGROUND;
|
||||
}
|
||||
|
||||
imlib_draw_image(image, other, args[ARG_x].u_int, args[ARG_y].u_int, x_scale, y_scale, &roi,
|
||||
args[ARG_channel].u_int, args[ARG_alpha].u_int, color_palette, alpha_palette,
|
||||
args[ARG_hint].u_int, callback, mask, dst_row_override);
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
return pos_args[0];
|
||||
}
|
||||
|
||||
static mp_obj_t py_image_draw_image(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return py_image_line_op(n_args, pos_args, kw_args, NULL);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_draw_image_obj, 1, py_image_draw_image);
|
||||
|
||||
#ifdef IMLIB_ENABLE_ISP_OPS
|
||||
//////////////
|
||||
@ -1957,149 +1978,35 @@ static mp_obj_t py_image_invert(mp_obj_t img_obj) {
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(py_image_invert_obj, py_image_invert);
|
||||
|
||||
static mp_obj_t py_image_b_and(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
image_t *arg_img =
|
||||
py_helper_arg_to_image(args[0], ARG_IMAGE_MUTABLE);
|
||||
image_t *arg_msk =
|
||||
py_helper_keyword_to_image(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_mask), NULL);
|
||||
|
||||
fb_alloc_mark();
|
||||
|
||||
if (MP_OBJ_IS_STR(args[1])) {
|
||||
imlib_b_and(arg_img, mp_obj_str_get_str(args[1]), NULL, 0, arg_msk);
|
||||
} else if (MP_OBJ_IS_TYPE(args[1], &py_image_type)) {
|
||||
imlib_b_and(arg_img, NULL, py_helper_arg_to_image(args[1], ARG_IMAGE_MUTABLE), 0, arg_msk);
|
||||
} else {
|
||||
imlib_b_and(arg_img, NULL, NULL,
|
||||
py_helper_keyword_color(arg_img, n_args, args, 1, NULL, 0),
|
||||
arg_msk);
|
||||
}
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
return args[0];
|
||||
static mp_obj_t py_image_b_and(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return py_image_line_op(n_args, pos_args, kw_args, imlib_b_and_line_op);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_b_and_obj, 2, py_image_b_and);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_b_and_obj, 1, py_image_b_and);
|
||||
|
||||
static mp_obj_t py_image_b_nand(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
image_t *arg_img =
|
||||
py_helper_arg_to_image(args[0], ARG_IMAGE_MUTABLE);
|
||||
image_t *arg_msk =
|
||||
py_helper_keyword_to_image(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_mask), NULL);
|
||||
|
||||
fb_alloc_mark();
|
||||
|
||||
if (MP_OBJ_IS_STR(args[1])) {
|
||||
imlib_b_nand(arg_img, mp_obj_str_get_str(args[1]), NULL, 0, arg_msk);
|
||||
} else if (MP_OBJ_IS_TYPE(args[1], &py_image_type)) {
|
||||
imlib_b_nand(arg_img, NULL, py_helper_arg_to_image(args[1], ARG_IMAGE_MUTABLE), 0, arg_msk);
|
||||
} else {
|
||||
imlib_b_nand(arg_img, NULL, NULL,
|
||||
py_helper_keyword_color(arg_img, n_args, args, 1, NULL, 0),
|
||||
arg_msk);
|
||||
}
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
return args[0];
|
||||
static mp_obj_t py_image_b_nand(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return py_image_line_op(n_args, pos_args, kw_args, imlib_b_nand_line_op);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_b_nand_obj, 2, py_image_b_nand);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_b_nand_obj, 1, py_image_b_nand);
|
||||
|
||||
static mp_obj_t py_image_b_or(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
image_t *arg_img =
|
||||
py_helper_arg_to_image(args[0], ARG_IMAGE_MUTABLE);
|
||||
image_t *arg_msk =
|
||||
py_helper_keyword_to_image(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_mask), NULL);
|
||||
|
||||
fb_alloc_mark();
|
||||
|
||||
if (MP_OBJ_IS_STR(args[1])) {
|
||||
imlib_b_or(arg_img, mp_obj_str_get_str(args[1]), NULL, 0, arg_msk);
|
||||
} else if (MP_OBJ_IS_TYPE(args[1], &py_image_type)) {
|
||||
imlib_b_or(arg_img, NULL, py_helper_arg_to_image(args[1], ARG_IMAGE_MUTABLE), 0, arg_msk);
|
||||
} else {
|
||||
imlib_b_or(arg_img, NULL, NULL,
|
||||
py_helper_keyword_color(arg_img, n_args, args, 1, NULL, 0),
|
||||
arg_msk);
|
||||
}
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
return args[0];
|
||||
static mp_obj_t py_image_b_or(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return py_image_line_op(n_args, pos_args, kw_args, imlib_b_or_line_op);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_b_or_obj, 2, py_image_b_or);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_b_or_obj, 1, py_image_b_or);
|
||||
|
||||
static mp_obj_t py_image_b_nor(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
image_t *arg_img =
|
||||
py_helper_arg_to_image(args[0], ARG_IMAGE_MUTABLE);
|
||||
image_t *arg_msk =
|
||||
py_helper_keyword_to_image(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_mask), NULL);
|
||||
|
||||
fb_alloc_mark();
|
||||
|
||||
if (MP_OBJ_IS_STR(args[1])) {
|
||||
imlib_b_nor(arg_img, mp_obj_str_get_str(args[1]), NULL, 0, arg_msk);
|
||||
} else if (MP_OBJ_IS_TYPE(args[1], &py_image_type)) {
|
||||
imlib_b_nor(arg_img, NULL, py_helper_arg_to_image(args[1], ARG_IMAGE_MUTABLE), 0, arg_msk);
|
||||
} else {
|
||||
imlib_b_nor(arg_img, NULL, NULL,
|
||||
py_helper_keyword_color(arg_img, n_args, args, 1, NULL, 0),
|
||||
arg_msk);
|
||||
}
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
return args[0];
|
||||
static mp_obj_t py_image_b_nor(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return py_image_line_op(n_args, pos_args, kw_args, imlib_b_nor_line_op);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_b_nor_obj, 2, py_image_b_nor);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_b_nor_obj, 1, py_image_b_nor);
|
||||
|
||||
static mp_obj_t py_image_b_xor(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
image_t *arg_img =
|
||||
py_helper_arg_to_image(args[0], ARG_IMAGE_MUTABLE);
|
||||
image_t *arg_msk =
|
||||
py_helper_keyword_to_image(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_mask), NULL);
|
||||
|
||||
fb_alloc_mark();
|
||||
|
||||
if (MP_OBJ_IS_STR(args[1])) {
|
||||
imlib_b_xor(arg_img, mp_obj_str_get_str(args[1]), NULL, 0, arg_msk);
|
||||
} else if (MP_OBJ_IS_TYPE(args[1], &py_image_type)) {
|
||||
imlib_b_xor(arg_img, NULL, py_helper_arg_to_image(args[1], ARG_IMAGE_MUTABLE), 0, arg_msk);
|
||||
} else {
|
||||
imlib_b_xor(arg_img, NULL, NULL,
|
||||
py_helper_keyword_color(arg_img, n_args, args, 1, NULL, 0),
|
||||
arg_msk);
|
||||
}
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
return args[0];
|
||||
static mp_obj_t py_image_b_xor(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return py_image_line_op(n_args, pos_args, kw_args, imlib_b_xor_line_op);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_b_xor_obj, 2, py_image_b_xor);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_b_xor_obj, 1, py_image_b_xor);
|
||||
|
||||
static mp_obj_t py_image_b_xnor(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
image_t *arg_img =
|
||||
py_helper_arg_to_image(args[0], ARG_IMAGE_MUTABLE);
|
||||
image_t *arg_msk =
|
||||
py_helper_keyword_to_image(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_mask), NULL);
|
||||
|
||||
fb_alloc_mark();
|
||||
|
||||
if (MP_OBJ_IS_STR(args[1])) {
|
||||
imlib_b_xnor(arg_img, mp_obj_str_get_str(args[1]), NULL, 0, arg_msk);
|
||||
} else if (MP_OBJ_IS_TYPE(args[1], &py_image_type)) {
|
||||
imlib_b_xnor(arg_img, NULL, py_helper_arg_to_image(args[1], ARG_IMAGE_MUTABLE), 0, arg_msk);
|
||||
} else {
|
||||
imlib_b_xnor(arg_img, NULL, NULL,
|
||||
py_helper_keyword_color(arg_img, n_args, args, 1, NULL, 0),
|
||||
arg_msk);
|
||||
}
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
return args[0];
|
||||
static mp_obj_t py_image_b_xnor(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return py_image_line_op(n_args, pos_args, kw_args, imlib_b_xnor_line_op);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_b_xnor_obj, 2, py_image_b_xnor);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_b_xnor_obj, 1, py_image_b_xnor);
|
||||
|
||||
static mp_obj_t py_image_binary_morph_op(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args,
|
||||
binary_morph_op_t op) {
|
||||
@ -2152,202 +2059,36 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_close_obj, 2, py_image_close);
|
||||
// Math Methods
|
||||
///////////////
|
||||
|
||||
static mp_obj_t py_image_replace(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
image_t *arg_img =
|
||||
py_helper_arg_to_image(args[0], ARG_IMAGE_MUTABLE);
|
||||
bool arg_hmirror =
|
||||
py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_hmirror), false);
|
||||
bool arg_vflip =
|
||||
py_helper_keyword_int(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_vflip), false);
|
||||
bool arg_transpose =
|
||||
py_helper_keyword_int(n_args, args, 4, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_transpose), false);
|
||||
image_t *arg_msk =
|
||||
py_helper_keyword_to_image(n_args, args, 5, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_mask), NULL);
|
||||
|
||||
if (arg_transpose) {
|
||||
size_t size0 = image_size(arg_img);
|
||||
int w = arg_img->w;
|
||||
int h = arg_img->h;
|
||||
arg_img->w = h;
|
||||
arg_img->h = w;
|
||||
size_t size1 = image_size(arg_img);
|
||||
arg_img->w = w;
|
||||
arg_img->h = h;
|
||||
PY_ASSERT_TRUE_MSG(size1 <= size0,
|
||||
"Unable to transpose the image because it would grow in size!");
|
||||
}
|
||||
|
||||
fb_alloc_mark();
|
||||
|
||||
mp_obj_t arg_1 = (n_args > 1) ? args[1] : args[0];
|
||||
|
||||
if (MP_OBJ_IS_STR(arg_1)) {
|
||||
imlib_replace(arg_img, mp_obj_str_get_str(arg_1), NULL, 0,
|
||||
arg_hmirror, arg_vflip, arg_transpose, arg_msk);
|
||||
} else if (MP_OBJ_IS_TYPE(arg_1, &py_image_type)) {
|
||||
imlib_replace(arg_img, NULL, py_helper_arg_to_image(arg_1, ARG_IMAGE_MUTABLE), 0,
|
||||
arg_hmirror, arg_vflip, arg_transpose, arg_msk);
|
||||
} else {
|
||||
imlib_replace(arg_img, NULL, NULL,
|
||||
py_helper_keyword_color(arg_img, n_args, args, 1, NULL, 0),
|
||||
arg_hmirror, arg_vflip, arg_transpose, arg_msk);
|
||||
}
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
py_helper_update_framebuffer(arg_img);
|
||||
return args[0];
|
||||
static mp_obj_t py_image_add(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return py_image_line_op(n_args, pos_args, kw_args, imlib_add_line_op);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_replace_obj, 1, py_image_replace);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_add_obj, 1, py_image_add);
|
||||
|
||||
static mp_obj_t py_image_add(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
image_t *arg_img =
|
||||
py_helper_arg_to_image(args[0], ARG_IMAGE_MUTABLE);
|
||||
image_t *arg_msk =
|
||||
py_helper_keyword_to_image(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_mask), NULL);
|
||||
|
||||
fb_alloc_mark();
|
||||
|
||||
if (MP_OBJ_IS_STR(args[1])) {
|
||||
imlib_add(arg_img, mp_obj_str_get_str(args[1]), NULL, 0, arg_msk);
|
||||
} else if (MP_OBJ_IS_TYPE(args[1], &py_image_type)) {
|
||||
imlib_add(arg_img, NULL, py_helper_arg_to_image(args[1], ARG_IMAGE_MUTABLE), 0, arg_msk);
|
||||
} else {
|
||||
imlib_add(arg_img, NULL, NULL,
|
||||
py_helper_keyword_color(arg_img, n_args, args, 1, NULL, 0),
|
||||
arg_msk);
|
||||
}
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
return args[0];
|
||||
static mp_obj_t py_image_sub(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return py_image_line_op(n_args, pos_args, kw_args, imlib_sub_line_op);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_add_obj, 2, py_image_add);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_sub_obj, 1, py_image_sub);
|
||||
|
||||
static mp_obj_t py_image_sub(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
image_t *arg_img =
|
||||
py_helper_arg_to_image(args[0], ARG_IMAGE_MUTABLE);
|
||||
bool arg_reverse =
|
||||
py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_reverse), false);
|
||||
image_t *arg_msk =
|
||||
py_helper_keyword_to_image(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_mask), NULL);
|
||||
|
||||
fb_alloc_mark();
|
||||
|
||||
if (MP_OBJ_IS_STR(args[1])) {
|
||||
imlib_sub(arg_img, mp_obj_str_get_str(args[1]), NULL, 0, arg_reverse, arg_msk);
|
||||
} else if (MP_OBJ_IS_TYPE(args[1], &py_image_type)) {
|
||||
imlib_sub(arg_img, NULL, py_helper_arg_to_image(args[1], ARG_IMAGE_MUTABLE), 0, arg_reverse, arg_msk);
|
||||
} else {
|
||||
imlib_sub(arg_img, NULL, NULL,
|
||||
py_helper_keyword_color(arg_img, n_args, args, 1, NULL, 0),
|
||||
arg_reverse, arg_msk);
|
||||
}
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
return args[0];
|
||||
static mp_obj_t py_image_rsub(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return py_image_line_op(n_args, pos_args, kw_args, imlib_rsub_line_op);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_sub_obj, 2, py_image_sub);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_rsub_obj, 1, py_image_rsub);
|
||||
|
||||
static mp_obj_t py_image_min(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
image_t *arg_img =
|
||||
py_helper_arg_to_image(args[0], ARG_IMAGE_MUTABLE);
|
||||
image_t *arg_msk =
|
||||
py_helper_keyword_to_image(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_mask), NULL);
|
||||
|
||||
fb_alloc_mark();
|
||||
|
||||
if (MP_OBJ_IS_STR(args[1])) {
|
||||
imlib_min(arg_img, mp_obj_str_get_str(args[1]), NULL, 0, arg_msk);
|
||||
} else if (MP_OBJ_IS_TYPE(args[1], &py_image_type)) {
|
||||
imlib_min(arg_img, NULL, py_helper_arg_to_image(args[1], ARG_IMAGE_MUTABLE), 0, arg_msk);
|
||||
} else {
|
||||
imlib_min(arg_img, NULL, NULL,
|
||||
py_helper_keyword_color(arg_img, n_args, args, 1, NULL, 0),
|
||||
arg_msk);
|
||||
}
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
return args[0];
|
||||
static mp_obj_t py_image_min(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return py_image_line_op(n_args, pos_args, kw_args, imlib_min_line_op);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_min_obj, 2, py_image_min);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_min_obj, 1, py_image_min);
|
||||
|
||||
static mp_obj_t py_image_max(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
image_t *arg_img =
|
||||
py_helper_arg_to_image(args[0], ARG_IMAGE_MUTABLE);
|
||||
image_t *arg_msk =
|
||||
py_helper_keyword_to_image(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_mask), NULL);
|
||||
|
||||
fb_alloc_mark();
|
||||
|
||||
if (MP_OBJ_IS_STR(args[1])) {
|
||||
imlib_max(arg_img, mp_obj_str_get_str(args[1]), NULL, 0, arg_msk);
|
||||
} else if (MP_OBJ_IS_TYPE(args[1], &py_image_type)) {
|
||||
imlib_max(arg_img, NULL, py_helper_arg_to_image(args[1], ARG_IMAGE_MUTABLE), 0, arg_msk);
|
||||
} else {
|
||||
imlib_max(arg_img, NULL, NULL,
|
||||
py_helper_keyword_color(arg_img, n_args, args, 1, NULL, 0),
|
||||
arg_msk);
|
||||
}
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
return args[0];
|
||||
static mp_obj_t py_image_max(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return py_image_line_op(n_args, pos_args, kw_args, imlib_max_line_op);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_max_obj, 2, py_image_max);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_max_obj, 1, py_image_max);
|
||||
|
||||
static mp_obj_t py_image_difference(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
image_t *arg_img =
|
||||
py_helper_arg_to_image(args[0], ARG_IMAGE_MUTABLE);
|
||||
image_t *arg_msk =
|
||||
py_helper_keyword_to_image(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_mask), NULL);
|
||||
|
||||
fb_alloc_mark();
|
||||
|
||||
if (MP_OBJ_IS_STR(args[1])) {
|
||||
imlib_difference(arg_img, mp_obj_str_get_str(args[1]), NULL, 0, arg_msk);
|
||||
} else if (MP_OBJ_IS_TYPE(args[1], &py_image_type)) {
|
||||
imlib_difference(arg_img, NULL, py_helper_arg_to_image(args[1], ARG_IMAGE_MUTABLE), 0, arg_msk);
|
||||
} else {
|
||||
imlib_difference(arg_img, NULL, NULL,
|
||||
py_helper_keyword_color(arg_img, n_args, args, 1, NULL, 0),
|
||||
arg_msk);
|
||||
}
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
return args[0];
|
||||
static mp_obj_t py_image_difference(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
return py_image_line_op(n_args, pos_args, kw_args, imlib_difference_line_op);
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_difference_obj, 2, py_image_difference);
|
||||
|
||||
static mp_obj_t py_image_blend(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
image_t *arg_img =
|
||||
py_helper_arg_to_image(args[0], ARG_IMAGE_MUTABLE);
|
||||
float arg_alpha =
|
||||
py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_alpha), 128) / 256.0f;
|
||||
PY_ASSERT_TRUE_MSG((0 <= arg_alpha) && (arg_alpha <= 1), "Error: 0 <= alpha <= 256!");
|
||||
image_t *arg_msk =
|
||||
py_helper_keyword_to_image(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_mask), NULL);
|
||||
|
||||
fb_alloc_mark();
|
||||
|
||||
if (MP_OBJ_IS_STR(args[1])) {
|
||||
imlib_blend(arg_img, mp_obj_str_get_str(args[1]), NULL, 0, arg_alpha, arg_msk);
|
||||
} else if (MP_OBJ_IS_TYPE(args[1], &py_image_type)) {
|
||||
imlib_blend(arg_img, NULL, py_helper_arg_to_image(args[1], ARG_IMAGE_MUTABLE), 0, arg_alpha, arg_msk);
|
||||
} else {
|
||||
imlib_blend(arg_img, NULL, NULL,
|
||||
py_helper_keyword_color(arg_img, n_args, args, 1, NULL, 0),
|
||||
arg_alpha, arg_msk);
|
||||
}
|
||||
|
||||
fb_alloc_free_till_mark();
|
||||
|
||||
return args[0];
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_blend_obj, 2, py_image_blend);
|
||||
#endif//IMLIB_ENABLE_MATH_OPS
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_image_difference_obj, 1, py_image_difference);
|
||||
#endif // IMLIB_ENABLE_MATH_OPS
|
||||
|
||||
#if defined(IMLIB_ENABLE_MATH_OPS) && defined(IMLIB_ENABLE_BINARY_OPS)
|
||||
static mp_obj_t py_image_top_hat(uint n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
@ -6623,18 +6364,19 @@ static const mp_rom_map_elem_t locals_dict_table[] = {
|
||||
{MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
#endif
|
||||
#ifdef IMLIB_ENABLE_MATH_OPS
|
||||
/* Math Methods */
|
||||
#ifdef IMLIB_ENABLE_MATH_OPS
|
||||
{MP_ROM_QSTR(MP_QSTR_negate), MP_ROM_PTR(&py_image_invert_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_assign), MP_ROM_PTR(&py_image_replace_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_replace), MP_ROM_PTR(&py_image_replace_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_set), MP_ROM_PTR(&py_image_replace_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_assign), MP_ROM_PTR(&py_image_draw_image_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_replace), MP_ROM_PTR(&py_image_draw_image_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_set), MP_ROM_PTR(&py_image_draw_image_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_add), MP_ROM_PTR(&py_image_add_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&py_image_sub_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_rsub), MP_ROM_PTR(&py_image_rsub_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_min), MP_ROM_PTR(&py_image_min_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_max), MP_ROM_PTR(&py_image_max_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_difference), MP_ROM_PTR(&py_image_difference_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_blend), MP_ROM_PTR(&py_image_blend_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_blend), MP_ROM_PTR(&py_image_draw_image_obj)},
|
||||
#else
|
||||
{MP_ROM_QSTR(MP_QSTR_negate), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_assign), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
@ -6653,7 +6395,7 @@ static const mp_rom_map_elem_t locals_dict_table[] = {
|
||||
#else
|
||||
{MP_ROM_QSTR(MP_QSTR_top_hat), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
{MP_ROM_QSTR(MP_QSTR_black_hat), MP_ROM_PTR(&py_func_unavailable_obj)},
|
||||
#endif //defined(IMLIB_ENABLE_MATH_OPS) && defined (IMLIB_ENABLE_BINARY_OPS)
|
||||
#endif // defined(IMLIB_ENABLE_MATH_OPS) && defined (IMLIB_ENABLE_BINARY_OPS)
|
||||
/* Filtering Methods */
|
||||
{MP_ROM_QSTR(MP_QSTR_histeq), MP_ROM_PTR(&py_image_histeq_obj)},
|
||||
#ifdef IMLIB_ENABLE_MEAN
|
||||
|
||||
Loading…
Reference in New Issue
Block a user