imlib: Update min/max usage to clamp and sat.

This commit is contained in:
Kwabena W. Agyeman 2024-02-24 13:41:17 -08:00
parent 47da5ec07c
commit 3705652b23
21 changed files with 204 additions and 215 deletions

View File

@ -963,12 +963,12 @@ static void imlib_erode_dilate(image_t *img, int ksize, int threshold, int e_or_
// slower (checks boundaries per pixel)
acc = e_or_d ? 0 : -1; // Don't count center pixel...
for (int j = -ksize; j <= ksize; j++) {
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
acc += IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
acc += IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr, x_k);
}
}
}
@ -1032,12 +1032,12 @@ static void imlib_erode_dilate(image_t *img, int ksize, int threshold, int e_or_
// slower way which checks boundaries per pixel
acc = e_or_d ? 0 : -1; // Don't count center pixel...
for (int j = -ksize; j <= ksize; j++) {
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
acc += (IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)))) > 0;
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
acc += IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr, x_k) > 0;
} // for k
} // for j
}
@ -1103,12 +1103,12 @@ static void imlib_erode_dilate(image_t *img, int ksize, int threshold, int e_or_
// need to check boundary conditions for each pixel
acc = e_or_d ? 0 : -1; // Don't count center pixel...
for (int j = -ksize; j <= ksize; j++) {
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
acc += (IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)))) > 0;
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
acc += IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr, x_k) > 0;
}
}
}

View File

@ -172,9 +172,9 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
// These values are initialized to their maximum before we minimize.
for (int i = 0; i < FIND_BLOBS_CORNERS_RESOLUTION; i++) {
corners[i].x =
IM_MAX(IM_MIN(x_max * sign(cos_table[FIND_BLOBS_ANGLE_RESOLUTION * i]), x_max), 0);
IM_CLAMP(x_max * sign(cos_table[FIND_BLOBS_ANGLE_RESOLUTION * i]), 0, x_max);
corners[i].y =
IM_MAX(IM_MIN(y_max * sign(sin_table[FIND_BLOBS_ANGLE_RESOLUTION * i]), y_max), 0);
IM_CLAMP(y_max * sign(sin_table[FIND_BLOBS_ANGLE_RESOLUTION * i]), 0, y_max);
corners_acc[i] = (corners[i].x * cos_table[FIND_BLOBS_ANGLE_RESOLUTION * i]) +
(corners[i].y * sin_table[FIND_BLOBS_ANGLE_RESOLUTION * i]);
corners_n[i] = 1;
@ -478,9 +478,9 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
// These values are initialized to their maximum before we minimize.
for (int i = 0; i < FIND_BLOBS_CORNERS_RESOLUTION; i++) {
corners[i].x =
IM_MAX(IM_MIN(x_max * sign(cos_table[FIND_BLOBS_ANGLE_RESOLUTION * i]), x_max), 0);
IM_CLAMP(x_max * sign(cos_table[FIND_BLOBS_ANGLE_RESOLUTION * i]), 0, x_max);
corners[i].y =
IM_MAX(IM_MIN(y_max * sign(sin_table[FIND_BLOBS_ANGLE_RESOLUTION * i]), y_max), 0);
IM_CLAMP(y_max * sign(sin_table[FIND_BLOBS_ANGLE_RESOLUTION * i]), 0, y_max);
corners_acc[i] = (corners[i].x * cos_table[FIND_BLOBS_ANGLE_RESOLUTION * i]) +
(corners[i].y * sin_table[FIND_BLOBS_ANGLE_RESOLUTION * i]);
corners_n[i] = 1;
@ -784,9 +784,9 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
// Ensures that maximum goes all the way to the edge of the image.
for (int i = 0; i < FIND_BLOBS_CORNERS_RESOLUTION; i++) {
corners[i].x =
IM_MAX(IM_MIN(x_max * sign(cos_table[FIND_BLOBS_ANGLE_RESOLUTION * i]), x_max), 0);
IM_CLAMP(x_max * sign(cos_table[FIND_BLOBS_ANGLE_RESOLUTION * i]), 0, x_max);
corners[i].y =
IM_MAX(IM_MIN(y_max * sign(sin_table[FIND_BLOBS_ANGLE_RESOLUTION * i]), y_max), 0);
IM_CLAMP(y_max * sign(sin_table[FIND_BLOBS_ANGLE_RESOLUTION * i]), 0, y_max);
corners_acc[i] = (corners[i].x * cos_table[FIND_BLOBS_ANGLE_RESOLUTION * i]) +
(corners[i].y * sin_table[FIND_BLOBS_ANGLE_RESOLUTION * i]);
corners_n[i] = 1;
@ -1107,10 +1107,10 @@ void imlib_find_blobs(list_t *out, image_t *ptr, rectangle_t *roi, unsigned int
list_pop_front(out, &tmp_blob);
rectangle_t temp;
temp.x = IM_MAX(IM_MIN(tmp_blob.rect.x - margin, INT16_MAX), INT16_MIN);
temp.y = IM_MAX(IM_MIN(tmp_blob.rect.y - margin, INT16_MAX), INT16_MIN);
temp.w = IM_MAX(IM_MIN(tmp_blob.rect.w + (margin * 2), INT16_MAX), 0);
temp.h = IM_MAX(IM_MIN(tmp_blob.rect.h + (margin * 2), INT16_MAX), 0);
temp.x = __SSAT(tmp_blob.rect.x - margin, 16);
temp.y = __SSAT(tmp_blob.rect.y - margin, 16);
temp.w = __USAT(tmp_blob.rect.w + (margin * 2), 15);
temp.h = __USAT(tmp_blob.rect.h + (margin * 2), 15);
if (rectangle_overlap(&(lnk_blob.rect), &temp)
&& ((merge_cb_arg == NULL) || merge_cb(merge_cb_arg, &lnk_blob, &tmp_blob))) {

View File

@ -170,12 +170,12 @@ void imlib_mean_filter(image_t *img, const int ksize, bool threshold, int offset
acc = 0;
for (int j = -ksize; j <= ksize; j++) {
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
acc += IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
acc += IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr, x_k);
}
}
}
@ -233,12 +233,12 @@ void imlib_mean_filter(image_t *img, const int ksize, bool threshold, int offset
} else {
acc = 0;
for (int j = -ksize; j <= ksize; j++) {
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
acc += IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
acc += IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr, x_k);
}
}
}
@ -306,12 +306,12 @@ void imlib_mean_filter(image_t *img, const int ksize, bool threshold, int offset
// check bounds and do full sum calculations
r_acc = g_acc = b_acc = 0;
for (int j = -ksize; j <= ksize; j++) {
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr, x_k);
r_acc += COLOR_RGB565_TO_R5(pixel);
g_acc += COLOR_RGB565_TO_G6(pixel);
b_acc += COLOR_RGB565_TO_B5(pixel);
@ -422,12 +422,12 @@ void imlib_median_filter(image_t *img, const int ksize, float percentile, bool t
} else {
sum = 0;
for (int j = -ksize; j <= ksize; j++) {
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
sum += IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
sum += IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr, x_k);
}
}
}
@ -489,12 +489,12 @@ void imlib_median_filter(image_t *img, const int ksize, float percentile, bool t
// slow way
memset(data, 0, 64);
for (int j = -ksize; j <= ksize; j++) {
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr, x_k);
data[pixel >> 2]++;
}
}
@ -565,12 +565,12 @@ void imlib_median_filter(image_t *img, const int ksize, float percentile, bool t
// need to check bounds
memset(r_data, 0, 32); memset(g_data, 0, 64); memset(b_data, 0, 32);
for (int j = -ksize; j <= ksize; j++) {
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr, x_k);
r_data[COLOR_RGB565_TO_R5(pixel)]++;
g_data[COLOR_RGB565_TO_G6(pixel)]++;
b_data[COLOR_RGB565_TO_B5(pixel)]++;
@ -672,11 +672,11 @@ void imlib_mode_filter(image_t *img, const int ksize, bool threshold, int offset
} else {
bins = 0;
for (int j = -ksize; j <= ksize; j++) {
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
bins += IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
bins += IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr, x_k);
}
}
}
@ -756,12 +756,12 @@ void imlib_mode_filter(image_t *img, const int ksize, bool threshold, int offset
mcount = -1;
memset(bins, 0, (COLOR_GRAYSCALE_MAX - COLOR_GRAYSCALE_MIN + 1));
for (int j = -ksize; j <= ksize; j++) {
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr, x_k);
bins[pixel]++;
if (bins[pixel] > mcount) {
@ -898,12 +898,12 @@ void imlib_mode_filter(image_t *img, const int ksize, bool threshold, int offset
memset(b_bins, 0, (COLOR_B5_MAX - COLOR_B5_MIN + 1));
r_mcount = g_mcount = b_mcount = 0;
for (int j = -ksize; j <= ksize; j++) {
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr, x_k);
r_pixel = COLOR_RGB565_TO_R5(pixel);
g_pixel = COLOR_RGB565_TO_G6(pixel);
b_pixel = COLOR_RGB565_TO_B5(pixel);
@ -1002,12 +1002,12 @@ void imlib_midpoint_filter(image_t *img, const int ksize, float bias, bool thres
}
} else {
for (int j = -ksize; j <= ksize; j++) {
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
int pixel = IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
int pixel = IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr, x_k);
min &= pixel;
max |= pixel;
}
@ -1073,12 +1073,12 @@ void imlib_midpoint_filter(image_t *img, const int ksize, float bias, bool thres
}
} else {
for (int j = -ksize; j <= ksize; j++) {
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr, x_k);
if (pixel < min) {
min = pixel;
} else if (pixel > max) {
@ -1162,12 +1162,12 @@ void imlib_midpoint_filter(image_t *img, const int ksize, float bias, bool thres
}
} else {
for (int j = -ksize; j <= ksize; j++) {
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr, x_k);
int r_pixel = COLOR_RGB565_TO_R5(pixel);
int g_pixel = COLOR_RGB565_TO_G6(pixel);
int b_pixel = COLOR_RGB565_TO_B5(pixel);
@ -1279,11 +1279,11 @@ void imlib_morph(image_t *img,
}
} else {
for (int j = -ksize; j <= ksize; j++) {
int y_j = IM_MIN(IM_MAX(y + j, 0), (img->h - 1));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
int x_k = IM_MIN(IM_MAX(x + k, 0), (img->w - 1));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
acc += krn[ptr++] * IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr, x_k);
}
}
@ -1456,11 +1456,11 @@ void imlib_morph(image_t *img,
}
} else {
for (int j = -ksize; j <= ksize; j++) {
int y_j = IM_MIN(IM_MAX(y + j, 0), (img->h - 1));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
int x_k = IM_MIN(IM_MAX(x + k, 0), (img->w - 1));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
acc += krn[ptr++] * IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr, x_k);
}
}
@ -1694,11 +1694,11 @@ void imlib_morph(image_t *img,
}
} else {
for (int j = -ksize; j <= ksize; j++) {
int y_j = IM_MIN(IM_MAX(y + j, 0), (img->h - 1));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
int x_k = IM_MIN(IM_MAX(x + k, 0), (img->w - 1));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr, x_k);
r_acc += krn[ptr] * COLOR_RGB565_TO_R5(pixel);
g_acc += krn[ptr] * COLOR_RGB565_TO_G6(pixel);
@ -1809,12 +1809,12 @@ void imlib_bilateral_filter(image_t *img,
float i_acc = 0, w_acc = 0;
int ptr = 0;
for (int j = -ksize; j <= ksize; j++) {
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint32_t *k_row_ptr = IMAGE_COMPUTE_BINARY_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
int pixel = IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
int pixel = IMAGE_GET_BINARY_PIXEL_FAST(k_row_ptr, x_k);
float w = gi_lut[(this_pixel - pixel)] * gs_lut[ptr++];
i_acc += pixel * w;
w_acc += w;
@ -1898,12 +1898,12 @@ void imlib_bilateral_filter(image_t *img,
}
} else {
for (int j = -ksize; j <= ksize; j++) {
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
int pixel = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr, x_k);
float w = gi_lut[(this_pixel - pixel)] * gs_lut[ptr++];
i_acc += pixel * w;
w_acc += w;
@ -2012,12 +2012,12 @@ void imlib_bilateral_filter(image_t *img,
} else {
// check boundary conditions
for (int j = -ksize; j <= ksize; j++) {
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img,
IM_MIN(IM_MAX(y + j, 0), (img->h - 1)));
int y_j = IM_CLAMP(y + j, 0, (img->h - 1));
uint16_t *k_row_ptr = IMAGE_COMPUTE_RGB565_PIXEL_ROW_PTR(img, y_j);
for (int k = -ksize; k <= ksize; k++) {
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr,
IM_MIN(IM_MAX(x + k, 0), (img->w - 1)));
int x_k = IM_CLAMP(x + k, 0, (img->w - 1));
int pixel = IMAGE_GET_RGB565_PIXEL_FAST(k_row_ptr, x_k);
int r_pixel = COLOR_RGB565_TO_R5(pixel);
int g_pixel = COLOR_RGB565_TO_G6(pixel);
int b_pixel = COLOR_RGB565_TO_B5(pixel);

View File

@ -432,7 +432,7 @@ int8_t imlib_rgb565_to_l(uint16_t pixel) {
y = (y > 0.008856f) ? fast_cbrtf(y) : ((y * 7.787037f) + 0.137931f);
return IM_MAX(IM_MIN(fast_floorf(116 * y) - 16, COLOR_L_MAX), COLOR_L_MIN);
return IM_CLAMP(fast_floorf(116 * y) - 16, COLOR_L_MIN, COLOR_L_MAX);
}
int8_t imlib_rgb565_to_a(uint16_t pixel) {
@ -446,7 +446,7 @@ int8_t imlib_rgb565_to_a(uint16_t pixel) {
x = (x > 0.008856f) ? fast_cbrtf(x) : ((x * 7.787037f) + 0.137931f);
y = (y > 0.008856f) ? fast_cbrtf(y) : ((y * 7.787037f) + 0.137931f);
return IM_MAX(IM_MIN(fast_floorf(500 * (x - y)), COLOR_A_MAX), COLOR_A_MIN);
return __SSAT(fast_floorf(500 * (x - y)), 8);
}
int8_t imlib_rgb565_to_b(uint16_t pixel) {
@ -460,7 +460,7 @@ int8_t imlib_rgb565_to_b(uint16_t pixel) {
y = (y > 0.008856f) ? fast_cbrtf(y) : ((y * 7.787037f) + 0.137931f);
z = (z > 0.008856f) ? fast_cbrtf(z) : ((z * 7.787037f) + 0.137931f);
return IM_MAX(IM_MIN(fast_floorf(200 * (y - z)), COLOR_B_MAX), COLOR_B_MIN);
return __SSAT(fast_floorf(200 * (y - z)), 8);
}
// https://en.wikipedia.org/wiki/Lab_color_space -> CIELAB-CIEXYZ conversions
@ -482,18 +482,18 @@ uint16_t imlib_lab_to_rgb(uint8_t l, int8_t a, int8_t b) {
g_lin = (g_lin > 0.0031308f) ? ((1.055f * powf(g_lin, 0.416666f)) - 0.055f) : (g_lin * 12.92f);
b_lin = (b_lin > 0.0031308f) ? ((1.055f * powf(b_lin, 0.416666f)) - 0.055f) : (b_lin * 12.92f);
uint32_t red = IM_MAX(IM_MIN(fast_floorf(r_lin * COLOR_R8_MAX), COLOR_R8_MAX), COLOR_R8_MIN);
uint32_t green = IM_MAX(IM_MIN(fast_floorf(g_lin * COLOR_G8_MAX), COLOR_G8_MAX), COLOR_G8_MIN);
uint32_t blue = IM_MAX(IM_MIN(fast_floorf(b_lin * COLOR_B8_MAX), COLOR_B8_MAX), COLOR_B8_MIN);
uint32_t red = __USAT(fast_floorf(r_lin * COLOR_R8_MAX), 8);
uint32_t green = __USAT(fast_floorf(g_lin * COLOR_G8_MAX), 8);
uint32_t blue = __USAT(fast_floorf(b_lin * COLOR_B8_MAX), 8);
return COLOR_R8_G8_B8_TO_RGB565(red, green, blue);
}
// https://en.wikipedia.org/wiki/YCbCr -> JPEG Conversion
uint16_t imlib_yuv_to_rgb(uint8_t y, int8_t u, int8_t v) {
uint32_t r = IM_MAX(IM_MIN(y + ((91881 * v) >> 16), COLOR_R8_MAX), COLOR_R8_MIN);
uint32_t g = IM_MAX(IM_MIN(y - (((22554 * u) + (46802 * v)) >> 16), COLOR_G8_MAX), COLOR_G8_MIN);
uint32_t b = IM_MAX(IM_MIN(y + ((116130 * u) >> 16), COLOR_B8_MAX), COLOR_B8_MIN);
uint32_t r = __USAT(y + ((91881 * v) >> 16), 8);
uint32_t g = __USAT(y - (((22554 * u) + (46802 * v)) >> 16), 8);
uint32_t b = __USAT(y + ((116130 * u) >> 16), 8);
return COLOR_R8_G8_B8_TO_RGB565(r, g, b);
}
@ -1155,7 +1155,7 @@ void imlib_sepconv3(image_t *img, const int8_t *krn, const float m, const int b)
acc = __SMLAD(krn[1], buffer[((y - 1) % 2) * img->w + x + 1], acc);
acc = __SMLAD(krn[2], buffer[((y - 1) % 2) * img->w + x + 2], acc);
acc = (acc * m) + b; // scale, offset, and clamp
acc = IM_MAX(IM_MIN(acc, IM_MAX_GS), 0);
acc = __USAT(acc, 8);
IM_SET_GS_PIXEL(img, (x + 1), (y), acc);
}
}

View File

@ -63,6 +63,8 @@
({__typeof__ (a) _a = (a); __typeof__ (b) _b = (b); \
__builtin_choose_expr(IM_SIGN_COMPARE(_a, _b), (void) 0, (_a < _b ? _a : _b)); })
#define IM_CLAMP(x, min, max) IM_MAX(IM_MIN((x), (max)), (min))
#define IM_DIV(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _b ? (_a / _b) : 0; })
#define IM_MOD(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _b ? (_a % _b) : 0; })

View File

@ -1045,7 +1045,7 @@ void imlib_gamma(image_t *img, float gamma, float contrast, float brightness) {
for (int i = COLOR_BINARY_MIN; i <= COLOR_BINARY_MAX; i++) {
int p = ((fast_powf(i * pDiv, gamma) * contrast) + brightness) * pScale;
p_lut[i] = IM_MIN(IM_MAX(p, COLOR_BINARY_MIN), COLOR_BINARY_MAX);
p_lut[i] = __USAT(p, 1);
}
for (int y = 0, yy = img->h; y < yy; y++) {
@ -1069,7 +1069,7 @@ void imlib_gamma(image_t *img, float gamma, float contrast, float brightness) {
for (int i = COLOR_GRAYSCALE_MIN; i <= COLOR_GRAYSCALE_MAX; i++) {
int p = ((fast_powf(i * pDiv, gamma) * contrast) + brightness) * pScale;
p_lut[i] = IM_MIN(IM_MAX(p, COLOR_GRAYSCALE_MIN), COLOR_GRAYSCALE_MAX);
p_lut[i] = __USAT(p, 8);
}
uint8_t *ptr = (uint8_t *) img->data;
@ -1101,17 +1101,17 @@ void imlib_gamma(image_t *img, float gamma, float contrast, float brightness) {
for (int i = COLOR_R5_MIN; i <= COLOR_R5_MAX; i++) {
int r = ((fast_powf(i * rDiv, gamma) * contrast) + brightness) * rScale;
r_lut[i] = IM_MIN(IM_MAX(r, COLOR_R5_MIN), COLOR_R5_MAX);
r_lut[i] = __USAT(r, 5);
}
for (int i = COLOR_G6_MIN; i <= COLOR_G6_MAX; i++) {
int g = ((fast_powf(i * gDiv, gamma) * contrast) + brightness) * gScale;
g_lut[i] = IM_MIN(IM_MAX(g, COLOR_G6_MIN), COLOR_G6_MAX);
g_lut[i] = __USAT(g, 6);
}
for (int i = COLOR_B5_MIN; i <= COLOR_B5_MAX; i++) {
int b = ((fast_powf(i * bDiv, gamma) * contrast) + brightness) * bScale;
b_lut[i] = IM_MIN(IM_MAX(b, COLOR_B5_MIN), COLOR_B5_MAX);
b_lut[i] = __USAT(b, 5);
}
uint16_t *ptr = (uint16_t *) img->data;

View File

@ -157,11 +157,11 @@ void imlib_stereo_disparity(image_t *img, bool reversed, int max_disparity, int
// slow way
for (int i = 0, j = -BLOCK_H_U; j <= BLOCK_H_D; j++) {
int y_p = y + j;
int y = IM_MIN(IM_MAX(y_p, 0), height_1_m_1);
int y = IM_CLAMP(y_p, 0, height_1_m_1);
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, y);
for (int k = -BLOCK_W_L; k <= BLOCK_W_R; k++) {
int x_p = xl + k;
int x = IM_MIN(IM_MAX(x_p, 0), width_2_m_1) + xl_offset;
int x = IM_CLAMP(x_p, 0, width_2_m_1) + xl_offset;
data_l[i++] = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr, x);
}
}
@ -179,11 +179,11 @@ void imlib_stereo_disparity(image_t *img, bool reversed, int max_disparity, int
// slow way
for (int i = 0, j = -BLOCK_H_U; j <= BLOCK_H_D; j++) {
int y_p = y + j;
int y = IM_MIN(IM_MAX(y_p, 0), height_1_m_1);
int y = IM_CLAMP(y_p, 0, height_1_m_1);
uint8_t *k_row_ptr = IMAGE_COMPUTE_GRAYSCALE_PIXEL_ROW_PTR(img, y);
for (int k = -BLOCK_W_L; k <= BLOCK_W_R; k++) {
int x_p = xr + k;
int x = IM_MIN(IM_MAX(x_p, 0), width_2_m_1) + xr_offset;
int x = IM_CLAMP(x_p, 0, width_2_m_1) + xr_offset;
data_r[i++] = IMAGE_GET_GRAYSCALE_PIXEL_FAST(k_row_ptr, x);
}
}

View File

@ -85,17 +85,17 @@ void imlib_deyuv_line(int x_start, int x_end, int y_row, void *dst_row_ptr, pixf
int by = (227 * v) >> 7;
int r0 = y0 + ry, g0 = y0 - gy, b0 = y0 + by;
r0 = IM_MIN(IM_MAX(r0, COLOR_R8_MIN), COLOR_R8_MAX);
g0 = IM_MIN(IM_MAX(g0, COLOR_G8_MIN), COLOR_G8_MAX);
b0 = IM_MIN(IM_MAX(b0, COLOR_B8_MIN), COLOR_B8_MAX);
r0 = __USAT(r0, 8);
g0 = __USAT(g0, 8);
b0 = __USAT(b0, 8);
int rgb565_0 = COLOR_R8_G8_B8_TO_RGB565(r0, g0, b0);
IMAGE_PUT_RGB565_PIXEL_FAST(row_ptr_16, x, rgb565_0);
if (x != w_limit) {
int r1 = y1 + ry, g1 = y1 - gy, b1 = y1 + by;
r1 = IM_MIN(IM_MAX(r1, COLOR_R8_MIN), COLOR_R8_MAX);
g1 = IM_MIN(IM_MAX(g1, COLOR_G8_MIN), COLOR_G8_MAX);
b1 = IM_MIN(IM_MAX(b1, COLOR_B8_MIN), COLOR_B8_MAX);
r1 = __USAT(r1, 8);
g1 = __USAT(g1, 8);
b1 = __USAT(b1, 8);
int rgb565_1 = COLOR_R8_G8_B8_TO_RGB565(r1, g1, b1);
IMAGE_PUT_RGB565_PIXEL_FAST(row_ptr_16, x + 1, rgb565_1);
}

View File

@ -333,9 +333,9 @@ int py_helper_keyword_color(image_t *img, uint n_args, const mp_obj_t *args, uin
} else {
mp_obj_t *arg_color;
mp_obj_get_array_fixed_n(kw_arg->value, 3, &arg_color);
default_val = COLOR_R8_G8_B8_TO_RGB565(IM_MAX(IM_MIN(mp_obj_get_int(arg_color[0]), COLOR_R8_MAX), COLOR_R8_MIN),
IM_MAX(IM_MIN(mp_obj_get_int(arg_color[1]), COLOR_G8_MAX), COLOR_G8_MIN),
IM_MAX(IM_MIN(mp_obj_get_int(arg_color[2]), COLOR_B8_MAX), COLOR_B8_MIN));
default_val = COLOR_R8_G8_B8_TO_RGB565(__USAT(mp_obj_get_int(arg_color[0]), 8),
__USAT(mp_obj_get_int(arg_color[1]), 8),
__USAT(mp_obj_get_int(arg_color[2]), 8));
switch (img->pixfmt) {
case PIXFORMAT_BINARY: {
default_val = COLOR_RGB565_TO_BINARY(default_val);
@ -356,9 +356,9 @@ int py_helper_keyword_color(image_t *img, uint n_args, const mp_obj_t *args, uin
} else {
mp_obj_t *arg_color;
mp_obj_get_array_fixed_n(args[arg_index], 3, &arg_color);
default_val = COLOR_R8_G8_B8_TO_RGB565(IM_MAX(IM_MIN(mp_obj_get_int(arg_color[0]), COLOR_R8_MAX), COLOR_R8_MIN),
IM_MAX(IM_MIN(mp_obj_get_int(arg_color[1]), COLOR_G8_MAX), COLOR_G8_MIN),
IM_MAX(IM_MIN(mp_obj_get_int(arg_color[2]), COLOR_B8_MAX), COLOR_B8_MIN));
default_val = COLOR_R8_G8_B8_TO_RGB565(__USAT(mp_obj_get_int(arg_color[0]), 8),
__USAT(mp_obj_get_int(arg_color[1]), 8),
__USAT(mp_obj_get_int(arg_color[2]), 8));
switch (img->pixfmt) {
case PIXFORMAT_BINARY: {
default_val = COLOR_RGB565_TO_BINARY(default_val);
@ -391,26 +391,18 @@ void py_helper_arg_to_thresholds(const mp_obj_t arg, list_t *thresholds) {
mp_obj_get_array(arg_thresholds[i], &arg_threshold_len, &arg_threshold);
if (arg_threshold_len) {
color_thresholds_list_lnk_data_t lnk_data;
lnk_data.LMin = (arg_threshold_len > 0) ? IM_MAX(IM_MIN(mp_obj_get_int(arg_threshold[0]),
IM_MAX(COLOR_L_MAX, COLOR_GRAYSCALE_MAX)),
IM_MIN(COLOR_L_MIN, COLOR_GRAYSCALE_MIN)) :
lnk_data.LMin = (arg_threshold_len > 0) ? __USAT(mp_obj_get_int(arg_threshold[0]), 8) :
IM_MIN(COLOR_L_MIN, COLOR_GRAYSCALE_MIN);
lnk_data.LMax = (arg_threshold_len > 1) ? IM_MAX(IM_MIN(mp_obj_get_int(arg_threshold[1]),
IM_MAX(COLOR_L_MAX, COLOR_GRAYSCALE_MAX)),
IM_MIN(COLOR_L_MIN, COLOR_GRAYSCALE_MIN)) :
lnk_data.LMax = (arg_threshold_len > 1) ? __USAT(mp_obj_get_int(arg_threshold[1]), 8) :
IM_MAX(COLOR_L_MAX, COLOR_GRAYSCALE_MAX);
lnk_data.AMin =
(arg_threshold_len > 2) ? IM_MAX(IM_MIN(mp_obj_get_int(arg_threshold[2]), COLOR_A_MAX),
COLOR_A_MIN) : COLOR_A_MIN;
(arg_threshold_len > 2) ? __SSAT(mp_obj_get_int(arg_threshold[2]), 8) : COLOR_A_MIN;
lnk_data.AMax =
(arg_threshold_len > 3) ? IM_MAX(IM_MIN(mp_obj_get_int(arg_threshold[3]), COLOR_A_MAX),
COLOR_A_MIN) : COLOR_A_MAX;
(arg_threshold_len > 3) ? __SSAT(mp_obj_get_int(arg_threshold[3]), 8) : COLOR_A_MAX;
lnk_data.BMin =
(arg_threshold_len > 4) ? IM_MAX(IM_MIN(mp_obj_get_int(arg_threshold[4]), COLOR_B_MAX),
COLOR_B_MIN) : COLOR_B_MIN;
(arg_threshold_len > 4) ? __SSAT(mp_obj_get_int(arg_threshold[4]), 8) : COLOR_B_MIN;
lnk_data.BMax =
(arg_threshold_len > 5) ? IM_MAX(IM_MIN(mp_obj_get_int(arg_threshold[5]), COLOR_B_MAX),
COLOR_B_MIN) : COLOR_B_MAX;
(arg_threshold_len > 5) ? __SSAT(mp_obj_get_int(arg_threshold[5]), 8) : COLOR_B_MAX;
color_thresholds_list_lnk_data_t lnk_data_tmp;
memcpy(&lnk_data_tmp, &lnk_data, sizeof(color_thresholds_list_lnk_data_t));
lnk_data.LMin = IM_MIN(lnk_data_tmp.LMin, lnk_data_tmp.LMax);

View File

@ -843,8 +843,8 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize) {
int readout_x_max = (ACTIVE_SENSOR_WIDTH - readout_w) / 2;
int readout_y_max = (ACTIVE_SENSOR_HEIGHT - readout_h) / 2;
readout_x = IM_MAX(IM_MIN(readout_x, readout_x_max), -readout_x_max);
readout_y = IM_MAX(IM_MIN(readout_y, readout_y_max), -readout_y_max);
readout_x = IM_CLAMP(readout_x, -readout_x_max, readout_x_max);
readout_y = IM_CLAMP(readout_y, -readout_y_max, readout_y_max);
// Step 1: Determine sub-readout window.
@ -866,11 +866,11 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize) {
uint16_t sensor_w = sub_readout_w + DUMMY_WIDTH_BUFFER; // camera hardware needs dummy pixels to sync
uint16_t sensor_h = sub_readout_h + DUMMY_HEIGHT_BUFFER; // camera hardware needs dummy lines to sync
uint16_t sensor_x = IM_MAX(IM_MIN((((ACTIVE_SENSOR_WIDTH - sensor_w) / 4) - (readout_x / 2)) * 2,
ACTIVE_SENSOR_WIDTH - sensor_w), -(DUMMY_WIDTH_BUFFER / 2)) + DUMMY_COLUMNS; // must be multiple of 2
uint16_t sensor_x = IM_CLAMP((((ACTIVE_SENSOR_WIDTH - sensor_w) / 4) - (readout_x / 2)) * 2,
-(DUMMY_WIDTH_BUFFER / 2), ACTIVE_SENSOR_WIDTH - sensor_w) + DUMMY_COLUMNS; // must be multiple of 2
uint16_t sensor_y = IM_MAX(IM_MIN((((ACTIVE_SENSOR_HEIGHT - sensor_h) / 4) - (readout_y / 2)) * 2,
ACTIVE_SENSOR_HEIGHT - sensor_h), -(DUMMY_HEIGHT_BUFFER / 2)) + DUMMY_LINES; // must be multiple of 2
uint16_t sensor_y = IM_CLAMP((((ACTIVE_SENSOR_HEIGHT - sensor_h) / 4) - (readout_y / 2)) * 2,
-(DUMMY_HEIGHT_BUFFER / 2), ACTIVE_SENSOR_HEIGHT - sensor_h) + DUMMY_LINES; // must be multiple of 2
// Step 3: Write regs.
@ -937,14 +937,12 @@ static int ioctl(sensor_t *sensor, int request, va_list ap) {
case IOCTL_SET_READOUT_WINDOW: {
int tmp_readout_x = va_arg(ap, int);
int tmp_readout_y = va_arg(ap, int);
int tmp_readout_w = IM_MAX(IM_MIN(va_arg(ap, int), ACTIVE_SENSOR_WIDTH),
resolution[sensor->framesize][0]);
int tmp_readout_h = IM_MAX(IM_MIN(va_arg(ap, int), ACTIVE_SENSOR_HEIGHT),
resolution[sensor->framesize][1]);
int tmp_readout_w = IM_CLAMP(va_arg(ap, int), resolution[sensor->framesize][0], ACTIVE_SENSOR_WIDTH);
int tmp_readout_h = IM_CLAMP(va_arg(ap, int), resolution[sensor->framesize][1], ACTIVE_SENSOR_HEIGHT);
int readout_x_max = (ACTIVE_SENSOR_WIDTH - tmp_readout_w) / 2;
int readout_y_max = (ACTIVE_SENSOR_HEIGHT - tmp_readout_h) / 2;
tmp_readout_x = IM_MAX(IM_MIN(tmp_readout_x, readout_x_max), -readout_x_max);
tmp_readout_y = IM_MAX(IM_MIN(tmp_readout_y, readout_y_max), -readout_y_max);
tmp_readout_x = IM_CLAMP(tmp_readout_x, -readout_x_max, readout_x_max);
tmp_readout_y = IM_CLAMP(tmp_readout_y, -readout_y_max, readout_y_max);
bool changed = (tmp_readout_x != readout_x) || (tmp_readout_y != readout_y) ||
(tmp_readout_w != readout_w) || (tmp_readout_h != readout_h);
readout_x = tmp_readout_x;

View File

@ -341,13 +341,13 @@ static int set_colorbar(sensor_t *sensor, int enable) {
static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain_db_ceiling) {
int ret = 0;
if ((enable == 0) && (!isnanf(gain_db)) && (!isinff(gain_db))) {
gain_db = IM_MAX(IM_MIN(gain_db, 24.0f), 0.0f);
gain_db = IM_CLAMP(gain_db, 0.0f, 24.0f);
int gain = fast_ceilf(logf(expf((gain_db / 20.0f) * M_LN10)) / M_LN2);
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AE_CTRL, 0); // Must disable AE
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, ANALOG_GAIN, ((gain & 0x7) << 4));
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, GRP_PARAM_HOLD, 0x01);
} else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
gain_db_ceiling = IM_MAX(IM_MIN(gain_db_ceiling, 24.0f), 0.0f);
gain_db_ceiling = IM_CLAMP(gain_db_ceiling, 0.0f, 24.0f);
int gain = fast_ceilf(logf(expf((gain_db_ceiling / 20.0f) * M_LN10) / M_LN2));
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, MAX_AGAIN_FULL, (gain & 0x7));
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, MAX_AGAIN_BIN2, (gain & 0x7));

View File

@ -536,12 +536,12 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
uint8_t ae_ctrl = 0;
int ret = omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, AE_CTRL, &ae_ctrl);
if (!enable && (!isnanf(gain_db)) && (!isinff(gain_db))) {
gain_db = IM_MAX(IM_MIN(gain_db, 24.0f), 0.0f);
gain_db = IM_CLAMP(gain_db, 0.0f, 24.0f);
uint8_t gain = fast_ceilf(logf(expf((gain_db / 20.0f) * M_LN10)) / M_LN2);
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AE_CTRL, (ae_ctrl & 0xFE));
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, ANALOG_GAIN, ((gain & 0x7) << 4));
} else if (enable && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
gain_db_ceiling = IM_MAX(IM_MIN(gain_db_ceiling, 24.0f), 0.0f);
gain_db_ceiling = IM_CLAMP(gain_db_ceiling, 0.0f, 24.0f);
uint8_t gain = fast_ceilf(logf(expf((gain_db_ceiling / 20.0f) * M_LN10)) / M_LN2);
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, MAX_AGAIN, (gain & 0x07));
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AE_CTRL, (ae_ctrl | 0x01));

View File

@ -245,6 +245,7 @@ static int ioctl(sensor_t *sensor, int request, va_list ap) {
float *arg_max_temp = va_arg(ap, float *);
float min_temp_range = (lepton.high_temp_mode) ? LEPTON_MIN_TEMP_HIGH : LEPTON_MIN_TEMP_NORM;
float max_temp_range = (lepton.high_temp_mode) ? LEPTON_MAX_TEMP_HIGH : LEPTON_MAX_TEMP_NORM;
// Don't use clamp here, the order of comparison is important.
lepton.min_temp = IM_MAX(IM_MIN(*arg_min_temp, *arg_max_temp), min_temp_range);
lepton.max_temp = IM_MIN(IM_MAX(*arg_max_temp, *arg_min_temp), max_temp_range);
break;
@ -440,9 +441,9 @@ static int snapshot(sensor_t *sensor, image_t *image, uint32_t flags) {
value = (value - 8192) + kelvin;
}
float celsius = (value * 0.01f) - 273.15f;
celsius = IM_MAX(IM_MIN(celsius, lepton.max_temp), lepton.min_temp);
value = IM_MAX(IM_MIN(IM_DIV(((celsius - lepton.min_temp) * 255),
(lepton.max_temp - lepton.min_temp)), 255), 0);
celsius = IM_CLAMP(celsius, lepton.min_temp, lepton.max_temp);
value = __USAT(IM_DIV(((celsius - lepton.min_temp) * 255),
(lepton.max_temp - lepton.min_temp)), 8);
}
int t_x = x - MAIN_FB()->x;

View File

@ -589,8 +589,8 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize) {
int readout_x_max = (ACTIVE_SENSOR_WIDTH - readout_w) / 2;
int readout_y_max = (ACTIVE_SENSOR_HEIGHT - readout_h) / 2;
readout_x = IM_MAX(IM_MIN(readout_x, readout_x_max), -readout_x_max);
readout_y = IM_MAX(IM_MIN(readout_y, readout_y_max), -readout_y_max);
readout_x = IM_CLAMP(readout_x, -readout_x_max, readout_x_max);
readout_y = IM_CLAMP(readout_y, -readout_y_max, readout_y_max);
// Step 1: Determine readout area and subsampling amount.
@ -613,9 +613,9 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize) {
uint16_t sensor_w = readout_w + DUMMY_WIDTH_BUFFER; // camera hardware needs dummy pixels to sync
uint16_t sensor_h = readout_h + DUMMY_HEIGHT_BUFFER; // camera hardware needs dummy lines to sync
uint16_t sensor_ws = IM_MAX(IM_MIN((((ACTIVE_SENSOR_WIDTH - sensor_w) / 4) + (readout_x / 2)) * 2,
ACTIVE_SENSOR_WIDTH - sensor_w),
-(DUMMY_WIDTH_BUFFER / 2)) + DUMMY_COLUMNS; // must be multiple of 2
uint16_t sensor_ws = IM_CLAMP((((ACTIVE_SENSOR_WIDTH - sensor_w) / 4) + (readout_x / 2)) * 2,
-(DUMMY_WIDTH_BUFFER / 2),
ACTIVE_SENSOR_WIDTH - sensor_w) + DUMMY_COLUMNS; // must be multiple of 2
uint16_t sensor_we = sensor_ws + sensor_w - 1;
int sensor_ws_mod = sensor_ws % (read_mode_div * 4); // multiple 4/8
@ -624,9 +624,9 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize) {
sensor_we += read_mode_div;
}
uint16_t sensor_hs = IM_MAX(IM_MIN((((ACTIVE_SENSOR_HEIGHT - sensor_h) / 4) - (readout_y / 2)) * 2,
ACTIVE_SENSOR_HEIGHT - sensor_h),
-(DUMMY_HEIGHT_BUFFER / 2)) + DUMMY_LINES; // must be multiple of 2
uint16_t sensor_hs = IM_CLAMP((((ACTIVE_SENSOR_HEIGHT - sensor_h) / 4) - (readout_y / 2)) * 2,
-(DUMMY_HEIGHT_BUFFER / 2),
ACTIVE_SENSOR_HEIGHT - sensor_h) + DUMMY_LINES; // must be multiple of 2
uint16_t sensor_he = sensor_hs + sensor_h - 1;
int sensor_hs_mod = sensor_hs % (read_mode_div * 4); // multiple 4/8
@ -785,7 +785,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
}
if ((enable == 0) && (!isnanf(gain_db)) && (!isinff(gain_db))) {
int gain = IM_MAX(IM_MIN(expf((gain_db / 20.0f) * M_LN10) * 32.0f, 0xffff), 0x0000);
int gain = __USAT(expf((gain_db / 20.0f) * M_LN10) * 32.0f, 16);
if (omv_i2c_writew2(&sensor->i2c_bus, sensor->slv_addr, MT9M114_REG_UVC_GAIN_CONTROL, gain) != 0) {
return -1;
@ -926,12 +926,12 @@ static int ioctl(sensor_t *sensor, int request, va_list ap) {
case IOCTL_SET_READOUT_WINDOW: {
int tmp_readout_x = va_arg(ap, int);
int tmp_readout_y = va_arg(ap, int);
int tmp_readout_w = IM_MAX(IM_MIN(va_arg(ap, int), ACTIVE_SENSOR_WIDTH), resolution[sensor->framesize][0]);
int tmp_readout_h = IM_MAX(IM_MIN(va_arg(ap, int), ACTIVE_SENSOR_HEIGHT), resolution[sensor->framesize][1]);
int tmp_readout_w = IM_CLAMP(va_arg(ap, int), resolution[sensor->framesize][0], ACTIVE_SENSOR_WIDTH);
int tmp_readout_h = IM_CLAMP(va_arg(ap, int), resolution[sensor->framesize][1], ACTIVE_SENSOR_HEIGHT);
int readout_x_max = (ACTIVE_SENSOR_WIDTH - tmp_readout_w) / 2;
int readout_y_max = (ACTIVE_SENSOR_HEIGHT - tmp_readout_h) / 2;
tmp_readout_x = IM_MAX(IM_MIN(tmp_readout_x, readout_x_max), -readout_x_max);
tmp_readout_y = IM_MAX(IM_MIN(tmp_readout_y, readout_y_max), -readout_y_max);
tmp_readout_x = IM_CLAMP(tmp_readout_x, -readout_x_max, readout_x_max);
tmp_readout_y = IM_CLAMP(tmp_readout_y, -readout_y_max, readout_y_max);
bool changed = (tmp_readout_x != readout_x) || (tmp_readout_y != readout_y) ||
(tmp_readout_w != readout_w) || (tmp_readout_h != readout_h);
readout_x = tmp_readout_x;

View File

@ -201,8 +201,8 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize) {
int readout_x_max = (ACTIVE_SENSOR_WIDTH - (w * read_mode_mul)) / 2;
int readout_y_max = (ACTIVE_SENSOR_HEIGHT - (h * read_mode_mul)) / 2;
readout_x = IM_MAX(IM_MIN(readout_x, readout_x_max), -readout_x_max);
readout_y = IM_MAX(IM_MIN(readout_y, readout_y_max), -readout_y_max);
readout_x = IM_CLAMP(readout_x, -readout_x_max, readout_x_max);
readout_y = IM_CLAMP(readout_y, -readout_y_max, readout_y_max);
ret |= omv_i2c_writew(&sensor->i2c_bus, sensor->slv_addr, col_start_addr,
readout_x_max - readout_x + MT9V0XX_COL_START_MIN); // sensor is mirrored by default
@ -269,7 +269,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
}
if ((enable == 0) && (!isnanf(gain_db)) && (!isinff(gain_db))) {
int gain = IM_MAX(IM_MIN(fast_roundf(expf((gain_db / 20.0f) * M_LN10) * 16.0f), 64), 16);
int gain = IM_CLAMP(fast_roundf(expf((gain_db / 20.0f) * M_LN10) * 16.0f), 16, 64);
ret |= omv_i2c_readw(&sensor->i2c_bus, sensor->slv_addr, MT9V0XX_ANALOG_GAIN, &reg);
ret |= omv_i2c_writew(&sensor->i2c_bus, sensor->slv_addr, MT9V0XX_ANALOG_GAIN, (reg & 0xFF80) | gain);
@ -279,7 +279,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
ret |= omv_i2c_writew(&sensor->i2c_bus, sensor->slv_addr, MT9V0X4_ANALOG_GAIN_B, (reg & 0xFF80) | gain);
}
} else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
int gain_ceiling = IM_MAX(IM_MIN(fast_roundf(expf((gain_db_ceiling / 20.0f) * M_LN10) * 16.0f), 64), 16);
int gain_ceiling = IM_CLAMP(fast_roundf(expf((gain_db_ceiling / 20.0f) * M_LN10) * 16.0f), 16, 64);
int max_gain = (is_mt9v0x4(sensor)) ? MT9V0X4_MAX_GAIN : MT9V0X2_MAX_GAIN;
ret |= omv_i2c_readw(&sensor->i2c_bus, sensor->slv_addr, max_gain, &reg);
@ -450,8 +450,8 @@ static int ioctl(sensor_t *sensor, int request, va_list ap) {
int tmp_readout_y = va_arg(ap, int);
int readout_x_max = (ACTIVE_SENSOR_WIDTH - tmp_readout_w) / 2;
int readout_y_max = (ACTIVE_SENSOR_HEIGHT - tmp_readout_h) / 2;
tmp_readout_x = IM_MAX(IM_MIN(tmp_readout_x, readout_x_max), -readout_x_max);
tmp_readout_y = IM_MAX(IM_MIN(tmp_readout_y, readout_y_max), -readout_y_max);
tmp_readout_x = IM_CLAMP(tmp_readout_x, -readout_x_max, readout_x_max);
tmp_readout_y = IM_CLAMP(tmp_readout_y, -readout_y_max, readout_y_max);
bool changed = (tmp_readout_x != readout_x) ||
(tmp_readout_y != readout_y);
readout_x = tmp_readout_x;

View File

@ -586,7 +586,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, COM8, (reg & (~COM8_AGC_EN)) | ((enable != 0) ? COM8_AGC_EN : 0));
if ((enable == 0) && (!isnanf(gain_db)) && (!isinff(gain_db))) {
float gain = IM_MAX(IM_MIN(expf((gain_db / 20.0f) * M_LN10), 32.0f), 1.0f);
float gain = IM_CLAMP(expf((gain_db / 20.0f) * M_LN10), 1.0f, 32.0f);
int gain_temp = fast_ceilf(logf(IM_MAX(gain / 2.0f, 1.0f)) / M_LN2);
int gain_hi = 0xF >> (4 - gain_temp);
@ -594,7 +594,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, GAIN, (gain_hi << 4) | (gain_lo << 0));
} else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
float gain_ceiling = IM_MAX(IM_MIN(expf((gain_db_ceiling / 20.0f) * M_LN10), 128.0f), 2.0f);
float gain_ceiling = IM_CLAMP(expf((gain_db_ceiling / 20.0f) * M_LN10), 2.0f, 128.0f);
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, COM9, &reg);
ret |=
@ -670,8 +670,7 @@ static int set_auto_exposure(sensor_t *sensor, int enable, int exposure_us) {
}
int exposure =
IM_MAX(IM_MIN(((exposure_us * (((OMV_CSI_XCLK_FREQUENCY / clk_rc) * pll_mult) / 1000000)) / t_pclk) / t_line,
0xFFFF), 0x0000);
__USAT(((exposure_us * (((OMV_CSI_XCLK_FREQUENCY / clk_rc) * pll_mult) / 1000000)) / t_pclk) / t_line, 16);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, BANK_SEL, BANK_SEL_SENSOR);

View File

@ -886,8 +886,8 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize) {
int readout_x_max = (ACTIVE_SENSOR_WIDTH - readout_w) / 2;
int readout_y_max = (ACTIVE_SENSOR_HEIGHT - readout_h) / 2;
readout_x = IM_MAX(IM_MIN(readout_x, readout_x_max), -readout_x_max);
readout_y = IM_MAX(IM_MIN(readout_y, readout_y_max), -readout_y_max);
readout_x = IM_CLAMP(readout_x, -readout_x_max, readout_x_max);
readout_y = IM_CLAMP(readout_y, -readout_y_max, readout_y_max);
// Step 1: Determine readout area and subsampling amount.
@ -905,13 +905,13 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize) {
uint16_t sensor_h = readout_h + DUMMY_HEIGHT_BUFFER; // camera hardware needs dummy lines to sync
uint16_t sensor_ws =
IM_MAX(IM_MIN((((ACTIVE_SENSOR_WIDTH - sensor_w) / 4) + (readout_x / 2)) * 2, ACTIVE_SENSOR_WIDTH - sensor_w),
-(DUMMY_WIDTH_BUFFER / 2)) + DUMMY_COLUMNS; // must be multiple of 2
IM_CLAMP((((ACTIVE_SENSOR_WIDTH - sensor_w) / 4) + (readout_x / 2)) * 2, -(DUMMY_WIDTH_BUFFER / 2),
ACTIVE_SENSOR_WIDTH - sensor_w) + DUMMY_COLUMNS; // must be multiple of 2
uint16_t sensor_we = sensor_ws + sensor_w - 1;
uint16_t sensor_hs =
IM_MAX(IM_MIN((((ACTIVE_SENSOR_HEIGHT - sensor_h) / 4) - (readout_y / 2)) * 2, ACTIVE_SENSOR_HEIGHT - sensor_h),
-(DUMMY_HEIGHT_BUFFER / 2)) + DUMMY_LINES; // must be multiple of 2
IM_CLAMP((((ACTIVE_SENSOR_HEIGHT - sensor_h) / 4) - (readout_y / 2)) * 2, -(DUMMY_HEIGHT_BUFFER / 2),
ACTIVE_SENSOR_HEIGHT - sensor_h) + DUMMY_LINES; // must be multiple of 2
uint16_t sensor_he = sensor_hs + sensor_h - 1;
// Step 3: Determine scaling window offset.
@ -1079,13 +1079,13 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AEC_PK_MANUAL, (reg & 0xFD) | ((enable == 0) << 1));
if ((enable == 0) && (!isnanf(gain_db)) && (!isinff(gain_db))) {
int gain = IM_MAX(IM_MIN(fast_roundf(expf((gain_db / 20.0f) * M_LN10) * 16.0f), 1023), 0);
int gain = __USAT(fast_roundf(expf((gain_db / 20.0f) * M_LN10) * 16.0f), 10);
ret |= omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, AEC_PK_REAL_GAIN_H, &reg);
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AEC_PK_REAL_GAIN_H, (reg & 0xFC) | (gain >> 8));
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AEC_PK_REAL_GAIN_L, gain);
} else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
int gain_ceiling = IM_MAX(IM_MIN(fast_roundf(expf((gain_db_ceiling / 20.0f) * M_LN10) * 16.0f), 1023), 0);
int gain_ceiling = __USAT(fast_roundf(expf((gain_db_ceiling / 20.0f) * M_LN10) * 16.0f), 10);
ret |= omv_i2c_readb2(&sensor->i2c_bus, sensor->slv_addr, AEC_GAIN_CEILING_H, &reg);
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AEC_GAIN_CEILING_H, (reg & 0xFC) | (gain_ceiling >> 8));
@ -1159,7 +1159,7 @@ static int set_auto_exposure(sensor_t *sensor, int enable, int exposure_us) {
int pclk_freq = calc_pclk_freq(spc0, spc1, spc2, spc3, sysrootdiv);
int clocks_per_us = pclk_freq / 1000000;
int exposure = IM_MAX(IM_MIN((exposure_us * clocks_per_us) / hts, 0xFFFF), 0x0000);
int exposure = __USAT((exposure_us * clocks_per_us) / hts, 16);
int new_vts = IM_MAX(exposure, vts);
@ -1215,9 +1215,9 @@ static int set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, floa
if ((enable == 0) && (!isnanf(r_gain_db)) && (!isnanf(g_gain_db)) && (!isnanf(b_gain_db))
&& (!isinff(r_gain_db)) && (!isinff(g_gain_db)) && (!isinff(b_gain_db))) {
int r_gain = IM_MAX(IM_MIN(fast_roundf(expf((r_gain_db / 20.0f) * M_LN10)), 4095), 0);
int g_gain = IM_MAX(IM_MIN(fast_roundf(expf((g_gain_db / 20.0f) * M_LN10)), 4095), 0);
int b_gain = IM_MAX(IM_MIN(fast_roundf(expf((b_gain_db / 20.0f) * M_LN10)), 4095), 0);
int r_gain = __USAT(fast_roundf(expf((r_gain_db / 20.0f) * M_LN10)), 12);
int g_gain = __USAT(fast_roundf(expf((g_gain_db / 20.0f) * M_LN10)), 12);
int b_gain = __USAT(fast_roundf(expf((b_gain_db / 20.0f) * M_LN10)), 12);
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AWB_R_GAIN_H, r_gain >> 8);
ret |= omv_i2c_writeb2(&sensor->i2c_bus, sensor->slv_addr, AWB_R_GAIN_L, r_gain);
@ -1338,12 +1338,12 @@ static int ioctl(sensor_t *sensor, int request, va_list ap) {
case IOCTL_SET_READOUT_WINDOW: {
int tmp_readout_x = va_arg(ap, int);
int tmp_readout_y = va_arg(ap, int);
int tmp_readout_w = IM_MAX(IM_MIN(va_arg(ap, int), ACTIVE_SENSOR_WIDTH), resolution[sensor->framesize][0]);
int tmp_readout_h = IM_MAX(IM_MIN(va_arg(ap, int), ACTIVE_SENSOR_HEIGHT), resolution[sensor->framesize][1]);
int tmp_readout_w = IM_CLAMP(va_arg(ap, int), resolution[sensor->framesize][0], ACTIVE_SENSOR_WIDTH);
int tmp_readout_h = IM_CLAMP(va_arg(ap, int), resolution[sensor->framesize][1], ACTIVE_SENSOR_HEIGHT);
int readout_x_max = (ACTIVE_SENSOR_WIDTH - tmp_readout_w) / 2;
int readout_y_max = (ACTIVE_SENSOR_HEIGHT - tmp_readout_h) / 2;
tmp_readout_x = IM_MAX(IM_MIN(tmp_readout_x, readout_x_max), -readout_x_max);
tmp_readout_y = IM_MAX(IM_MIN(tmp_readout_y, readout_y_max), -readout_y_max);
tmp_readout_x = IM_CLAMP(tmp_readout_x, -readout_x_max, readout_x_max);
tmp_readout_y = IM_CLAMP(tmp_readout_y, -readout_y_max, readout_y_max);
bool changed = (tmp_readout_x != readout_x) || (tmp_readout_y != readout_y) || (tmp_readout_w != readout_w) ||
(tmp_readout_h != readout_h);
readout_x = tmp_readout_x;

View File

@ -381,7 +381,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, REG13, (reg & 0xFB) | ((enable != 0) << 2));
if ((enable == 0) && (!isnanf(gain_db)) && (!isinff(gain_db))) {
float gain = IM_MAX(IM_MIN(expf((gain_db / 20.0f) * M_LN10), 128.0f), 1.0f);
float gain = IM_CLAMP(expf((gain_db / 20.0f) * M_LN10), 1.0f, 128.0f);
int gain_temp = fast_ceilf(logf(IM_MAX(gain / 2.0f, 1.0f)) / M_LN2);
int gain_hi = 0x3F >> (6 - gain_temp);
@ -391,7 +391,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, REG15, &reg);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, REG15, (reg & 0xFC) | (gain_hi >> 4));
} else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
float gain_ceiling = IM_MAX(IM_MIN(expf((gain_db_ceiling / 20.0f) * M_LN10), 128.0f), 2.0f);
float gain_ceiling = IM_CLAMP(expf((gain_db_ceiling / 20.0f) * M_LN10), 2.0f, 128.0f);
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, REG14, &reg);
ret |=
@ -453,9 +453,8 @@ static int set_auto_exposure(sensor_t *sensor, int enable, int exposure_us) {
}
int exposure =
IM_MAX(IM_MIN(((exposure_us * ((((OMV_OV7690_XCLK_FREQ / clk_rc) * pll_mult) / pll_div) / 1000000)) / t_pclk) /
t_line,
0xFFFF), 0x0000);
__USAT(((exposure_us * ((((OMV_OV7690_XCLK_FREQ / clk_rc) * pll_mult) / pll_div) / 1000000)) / t_pclk) /
t_line, 16);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, AECL, ((exposure >> 0) & 0xFF));
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, AECH, ((exposure >> 8) & 0xFF));
@ -511,9 +510,9 @@ static int set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, floa
if ((enable == 0) && (!isnanf(r_gain_db)) && (!isnanf(g_gain_db)) && (!isnanf(b_gain_db))
&& (!isinff(r_gain_db)) && (!isinff(g_gain_db)) && (!isinff(b_gain_db))) {
int r_gain = IM_MAX(IM_MIN(fast_roundf(expf((r_gain_db / 20.0f) * M_LN10)), 255), 0);
int g_gain = IM_MAX(IM_MIN(fast_roundf(expf((g_gain_db / 20.0f) * M_LN10)), 255), 0);
int b_gain = IM_MAX(IM_MIN(fast_roundf(expf((b_gain_db / 20.0f) * M_LN10)), 255), 0);
int r_gain = __USAT(fast_roundf(expf((r_gain_db / 20.0f) * M_LN10)), 8);
int g_gain = __USAT(fast_roundf(expf((g_gain_db / 20.0f) * M_LN10)), 8);
int b_gain = __USAT(fast_roundf(expf((b_gain_db / 20.0f) * M_LN10)), 8);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, BGAIN, b_gain);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, RGAIN, r_gain);

View File

@ -346,7 +346,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, COM8, COM8_SET_AGC(reg, (enable != 0)));
if ((enable == 0) && (!isnanf(gain_db)) && (!isinff(gain_db))) {
float gain = IM_MAX(IM_MIN(expf((gain_db / 20.0f) * M_LN10), 32.0f), 1.0f);
float gain = IM_CLAMP(expf((gain_db / 20.0f) * M_LN10), 1.0f, 32.0f);
int gain_temp = fast_ceilf(logf(IM_MAX(gain / 2.0f, 1.0f)) / M_LN2);
int gain_hi = 0xF >> (4 - gain_temp);
@ -354,7 +354,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, GAIN, (gain_hi << 4) | (gain_lo << 0));
} else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinff(gain_db_ceiling))) {
float gain_ceiling = IM_MAX(IM_MIN(expf((gain_db_ceiling / 20.0f) * M_LN10), 32.0f), 2.0f);
float gain_ceiling = IM_CLAMP(expf((gain_db_ceiling / 20.0f) * M_LN10), 2.0f, 32.0f);
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, COM9, &reg);
ret |=
@ -427,8 +427,7 @@ static int set_auto_exposure(sensor_t *sensor, int enable, int exposure_us) {
}
int exposure =
IM_MAX(IM_MIN(((exposure_us * (((OMV_CSI_XCLK_FREQUENCY / clk_rc) * pll_mult) / 1000000)) / t_pclk) / t_line,
0xFFFF), 0x0000);
__USAT(((exposure_us * (((OMV_CSI_XCLK_FREQUENCY / clk_rc) * pll_mult) / 1000000)) / t_pclk) / t_line, 16);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, AEC, ((exposure >> 0) & 0xFF));
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, AECH, ((exposure >> 8) & 0xFF));
@ -502,9 +501,9 @@ static int set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, floa
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, AWB_CTRL1, &reg);
float gain_div = (reg & 0x2) ? 64.0f : 128.0f;
int r_gain = IM_MAX(IM_MIN(fast_roundf(expf((r_gain_db / 20.0f) * M_LN10) * gain_div), 255), 0);
int g_gain = IM_MAX(IM_MIN(fast_roundf(expf((g_gain_db / 20.0f) * M_LN10) * gain_div), 255), 0);
int b_gain = IM_MAX(IM_MIN(fast_roundf(expf((b_gain_db / 20.0f) * M_LN10) * gain_div), 255), 0);
int r_gain = __USAT(fast_roundf(expf((r_gain_db / 20.0f) * M_LN10) * gain_div), 8);
int g_gain = __USAT(fast_roundf(expf((g_gain_db / 20.0f) * M_LN10) * gain_div), 8);
int b_gain = __USAT(fast_roundf(expf((b_gain_db / 20.0f) * M_LN10) * gain_div), 8);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, BLUE, b_gain);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, RED, r_gain);

View File

@ -331,7 +331,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
(reg & (~REG_COM8_AGC)) | ((enable != 0) ? REG_COM8_AGC : 0));
if ((enable == 0) && (!isnanf(gain_db)) && (!isinf(gain_db))) {
float gain = IM_MAX(IM_MIN(expf((gain_db / 20.0f) * M_LN10), 128.0f), 1.0f);
float gain = IM_CLAMP(expf((gain_db / 20.0f) * M_LN10), 1.0f, 128.0f);
int gain_temp = fast_ceilf(logf(IM_MAX(gain / 2.0f, 1.0f)) / M_LN2);
int gain_hi = 0x3F >> (6 - gain_temp);
@ -341,7 +341,7 @@ static int set_auto_gain(sensor_t *sensor, int enable, float gain_db, float gain
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, REG_VREF, &reg);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, REG_VREF, ((gain_hi & 0x30) << 2) | (reg & 0x3F));
} else if ((enable != 0) && (!isnanf(gain_db_ceiling)) && (!isinf(gain_db_ceiling))) {
float gain_ceiling = IM_MAX(IM_MIN(expf((gain_db_ceiling / 20.0f) * M_LN10), 128.0f), 2.0f);
float gain_ceiling = IM_CLAMP(expf((gain_db_ceiling / 20.0f) * M_LN10), 2.0f, 128.0f);
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, REG_COM9, &reg);
ret |=
@ -413,8 +413,7 @@ static int set_auto_exposure(sensor_t *sensor, int enable, int exposure_us) {
int clk_rc = ((reg & REG_CLKRC_DIVIDER_MASK) + 1) * 2;
int exposure =
IM_MAX(IM_MIN(((exposure_us * (((OMV_CSI_XCLK_FREQUENCY / clk_rc) * pll_mult) / 1000000)) / t_pclk) / t_line,
0xFFFF), 0x0000);
__USAT(((exposure_us * (((OMV_CSI_XCLK_FREQUENCY / clk_rc) * pll_mult) / 1000000)) / t_pclk) / t_line, 16);
ret |= omv_i2c_readb(&sensor->i2c_bus, sensor->slv_addr, REG_COM1, &reg);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, REG_COM1, (reg & 0xFC) | ((exposure >> 0) & 0x3));
@ -486,8 +485,8 @@ static int set_auto_whitebal(sensor_t *sensor, int enable, float r_gain_db, floa
if ((enable == 0) && (!isnanf(r_gain_db)) && (!isnanf(g_gain_db)) && (!isnanf(b_gain_db))
&& (!isinff(r_gain_db)) && (!isinff(g_gain_db)) && (!isinff(b_gain_db))) {
int r_gain = IM_MAX(IM_MIN(fast_roundf(expf((r_gain_db / 20.0f) * M_LN10) * 128.0f), 255), 0);
int b_gain = IM_MAX(IM_MIN(fast_roundf(expf((b_gain_db / 20.0f) * M_LN10) * 128.0f), 255), 0);
int r_gain = __USAT(fast_roundf(expf((r_gain_db / 20.0f) * M_LN10) * 128.0f), 8);
int b_gain = __USAT(fast_roundf(expf((b_gain_db / 20.0f) * M_LN10) * 128.0f), 8);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, REG_BLUE, b_gain);
ret |= omv_i2c_writeb(&sensor->i2c_bus, sensor->slv_addr, REG_RED, r_gain);

View File

@ -294,7 +294,7 @@ static void auto_exposure(sensor_t *sensor) {
uint32_t GEP = gain * expo;
float l_ratio = ((float) l_target_total) / l_total;
float GEP_target = GEP * l_ratio;
uint32_t expo_target = IM_MIN(IM_MAX(fast_roundf(GEP_target / R_AE_MinGain), R_AE_MinExpoTime), R_AE_MaxExpoTime);
uint32_t expo_target = IM_CLAMP(fast_roundf(GEP_target / R_AE_MinGain), R_AE_MinExpoTime, R_AE_MaxExpoTime);
#ifdef DEBUG_AE
printf("GEP: %ld ", GEP);
@ -313,9 +313,9 @@ static void auto_exposure(sensor_t *sensor) {
} else {
gain_target = 8;
}
//gain_target = IM_MIN(IM_MAX(fast_ceilf(GEP_target/expo_target), R_AE_MinGain), R_AE_MaxGain);
//gain_target = IM_CLAMP(fast_ceilf(GEP_target/expo_target), R_AE_MinGain, R_AE_MaxGain);
gain_db = 20 * log10f((float) gain_target);
expo_target = IM_MIN(IM_MAX(fast_roundf(GEP_target / gain_target), R_AE_MinExpoTime), R_AE_MaxExpoTime);
expo_target = IM_CLAMP(fast_roundf(GEP_target / gain_target), R_AE_MinExpoTime, R_AE_MaxExpoTime);
#ifdef DEBUG_AE
printf("Gain Target: %ld (%d DB (x1000))\n", gain_target, (int) (gain_db * 1000));
printf("Final Expo Target: %ld (max: %ld) \n", expo_target, R_AE_MaxExpoTime);