Merge pull request #2368 from kwagyeman/kwabena/simd_bayer

imlib: Optimize debayering with Helium.
This commit is contained in:
Ibrahim Abdelkader 2024-08-25 23:31:30 +03:00 committed by GitHub
commit 1bc41e1850
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 4137 additions and 1489 deletions

View File

@ -148,4 +148,8 @@
// Stereo Imaging
// #define IMLIB_ENABLE_STEREO_DISPARITY
// Bayer
#define IMLIB_ENABLE_DEBAYER_OPTIMIZATION
#endif //__IMLIB_CONFIG_H__

File diff suppressed because it is too large Load Diff

View File

@ -1165,8 +1165,10 @@ void imlib_fill_image_from_float(image_t *img, int w, int h, float *data, float
// Bayer Image Processing
pixformat_t imlib_bayer_shift(pixformat_t pixfmt, int x, int y, bool transpose);
void imlib_debayer_ycbcr(image_t *src, rectangle_t *roi, int8_t *Y0, int8_t *CB, int8_t *CR);
void imlib_debayer_line(int x_start, int x_end, int y_row, void *dst_row_ptr, pixformat_t pixfmt, image_t *src);
void imlib_debayer_image(image_t *dst, image_t *src);
void imlib_debayer_image_awb(image_t *dst, image_t *src, bool fast, uint32_t r_out, uint32_t g_out, uint32_t b_out);
// YUV Image Processing
pixformat_t imlib_yuv_shift(pixformat_t pixfmt, int x);

View File

@ -295,665 +295,14 @@ void jpeg_get_mcu(image_t *src, int x_offset, int y_offset, int dx, int dy,
memset(CR, 0, JPEG_444_GS_MCU_SIZE);
}
int src_w = src->w, w_limit = src_w - 1, w_limit_m_1 = w_limit - 1;
int src_h = src->h, h_limit = src_h - 1, h_limit_m_1 = h_limit - 1;
if (x_offset && y_offset && (x_offset < (src_w - JPEG_MCU_W)) && (y_offset < (src_h - JPEG_MCU_H))) {
for (int y = y_offset - 1, yy = y + JPEG_MCU_H - 1, index_e = 0, index_o = JPEG_MCU_W; y < yy; y += 2,
index_e += JPEG_MCU_W,
index_o += JPEG_MCU_W) {
uint8_t *rowptr_grgr_0 = src->data + (y * src_w);
uint8_t *rowptr_bgbg_1 = rowptr_grgr_0 + src_w;
uint8_t *rowptr_grgr_2 = rowptr_bgbg_1 + src_w;
uint8_t *rowptr_bgbg_3 = rowptr_grgr_2 + src_w;
for (int x = x_offset - 1, xx = x + JPEG_MCU_W - 1; x < xx; x += 2, index_e += 2, index_o += 2) {
uint32_t row_grgr_0 = *((uint32_t *) (rowptr_grgr_0 + x));
uint32_t row_bgbg_1 = *((uint32_t *) (rowptr_bgbg_1 + x));
uint32_t row_grgr_2 = *((uint32_t *) (rowptr_grgr_2 + x));
uint32_t row_bgbg_3 = *((uint32_t *) (rowptr_bgbg_3 + x));
int r_pixels_0, g_pixels_0, b_pixels_0;
switch (src->pixfmt) {
case PIXFORMAT_BAYER_BGGR: {
#if defined(ARM_MATH_DSP)
int row_02 = __UHADD8(row_grgr_0, row_grgr_2);
int row_1g = __UHADD8(row_bgbg_1, __PKHTB(row_bgbg_1, row_bgbg_1, 16));
r_pixels_0 = __UXTB16(__UHADD8(row_02, __PKHTB(row_02, row_02, 16)));
g_pixels_0 = __UXTB16(__UHADD8(row_1g, __PKHTB(row_1g, row_02, 8)));
b_pixels_0 = __UXTB16_RORn(__UHADD8(row_bgbg_1, __PKHBT(row_bgbg_1, row_bgbg_1, 16)), 8);
#else
int r0 = ((row_grgr_0 & 0xFF) + (row_grgr_2 & 0xFF)) >> 1;
int r2 = (((row_grgr_0 >> 16) & 0xFF) + ((row_grgr_2 >> 16) & 0xFF)) >> 1;
r_pixels_0 = (r2 << 16) | ((r0 + r2) >> 1);
int g0 = (row_grgr_0 >> 8) & 0xFF;
int g1 = (((row_bgbg_1 >> 16) & 0xFF) + (row_bgbg_1 & 0xFF)) >> 1;
int g2 = (row_grgr_2 >> 8) & 0xFF;
g_pixels_0 = (row_bgbg_1 & 0xFF0000) | ((((g0 + g2) >> 1) + g1) >> 1);
int b1 = (((row_bgbg_1 >> 24) & 0xFF) + ((row_bgbg_1 >> 8) & 0xFF)) >> 1;
b_pixels_0 = (b1 << 16) | ((row_bgbg_1 >> 8) & 0xFF);
#endif
break;
}
case PIXFORMAT_BAYER_GBRG: {
#if defined(ARM_MATH_DSP)
int row_02 = __UHADD8(row_grgr_0, row_grgr_2);
int row_1g = __UHADD8(row_bgbg_1, __PKHBT(row_bgbg_1, row_bgbg_1, 16));
r_pixels_0 = __UXTB16_RORn(__UHADD8(row_02, __PKHBT(row_02, row_02, 16)), 8);
g_pixels_0 = __UXTB16_RORn(__UHADD8(row_1g, __PKHBT(row_1g, row_02, 8)), 8);
b_pixels_0 = __UXTB16(__UHADD8(row_bgbg_1, __PKHTB(row_bgbg_1, row_bgbg_1, 16)));
#else
int r0 = (((row_grgr_0 >> 8) & 0xFF) + ((row_grgr_2 >> 8) & 0xFF)) >> 1;
int r2 = (((row_grgr_0 >> 24) & 0xFF) + ((row_grgr_2 >> 24) & 0xFF)) >> 1;
r_pixels_0 = r0 | (((r0 + r2) >> 1) << 16);
int g0 = (row_grgr_0 >> 16) & 0xFF;
int g1 = (((row_bgbg_1 >> 24) & 0xFF) + ((row_bgbg_1 >> 8) & 0xFF)) >> 1;
int g2 = (row_grgr_2 >> 16) & 0xFF;
g_pixels_0 = ((row_bgbg_1 >> 8) & 0xFF) | (((((g0 + g2) >> 1) + g1) >> 1) << 16);
int b1 = (((row_bgbg_1 >> 16) & 0xFF) + (row_bgbg_1 & 0xFF)) >> 1;
b_pixels_0 = b1 | (row_bgbg_1 & 0xFF0000);
#endif
break;
}
case PIXFORMAT_BAYER_GRBG: {
#if defined(ARM_MATH_DSP)
int row_02 = __UHADD8(row_grgr_0, row_grgr_2);
int row_1g = __UHADD8(row_bgbg_1, __PKHBT(row_bgbg_1, row_bgbg_1, 16));
r_pixels_0 = __UXTB16(__UHADD8(row_bgbg_1, __PKHTB(row_bgbg_1, row_bgbg_1, 16)));
g_pixels_0 = __UXTB16_RORn(__UHADD8(row_1g, __PKHBT(row_1g, row_02, 8)), 8);
b_pixels_0 = __UXTB16_RORn(__UHADD8(row_02, __PKHBT(row_02, row_02, 16)), 8);
#else
int r1 = (((row_bgbg_1 >> 16) & 0xFF) + (row_bgbg_1 & 0xFF)) >> 1;
r_pixels_0 = r1 | (row_bgbg_1 & 0xFF0000);
int g0 = (row_grgr_0 >> 16) & 0xFF;
int g1 = (((row_bgbg_1 >> 24) & 0xFF) + ((row_bgbg_1 >> 8) & 0xFF)) >> 1;
int g2 = (row_grgr_2 >> 16) & 0xFF;
g_pixels_0 = ((row_bgbg_1 >> 8) & 0xFF) | (((((g0 + g2) >> 1) + g1) >> 1) << 16);
int b0 = (((row_grgr_0 >> 8) & 0xFF) + ((row_grgr_2 >> 8) & 0xFF)) >> 1;
int b2 = (((row_grgr_0 >> 24) & 0xFF) + ((row_grgr_2 >> 24) & 0xFF)) >> 1;
b_pixels_0 = b0 | (((b0 + b2) >> 1) << 16);
#endif
break;
}
case PIXFORMAT_BAYER_RGGB: {
#if defined(ARM_MATH_DSP)
int row_02 = __UHADD8(row_grgr_0, row_grgr_2);
int row_1g = __UHADD8(row_bgbg_1, __PKHTB(row_bgbg_1, row_bgbg_1, 16));
r_pixels_0 = __UXTB16_RORn(__UHADD8(row_bgbg_1, __PKHBT(row_bgbg_1, row_bgbg_1, 16)), 8);
g_pixels_0 = __UXTB16(__UHADD8(row_1g, __PKHTB(row_1g, row_02, 8)));
b_pixels_0 = __UXTB16(__UHADD8(row_02, __PKHTB(row_02, row_02, 16)));
#else
int r1 = (((row_bgbg_1 >> 24) & 0xFF) + ((row_bgbg_1 >> 8) & 0xFF)) >> 1;
r_pixels_0 = (r1 << 16) | ((row_bgbg_1 >> 8) & 0xFF);
int g0 = (row_grgr_0 >> 8) & 0xFF;
int g1 = (((row_bgbg_1 >> 16) & 0xFF) + (row_bgbg_1 & 0xFF)) >> 1;
int g2 = (row_grgr_2 >> 8) & 0xFF;
g_pixels_0 = (row_bgbg_1 & 0xFF0000) | ((((g0 + g2) >> 1) + g1) >> 1);
int b0 = ((row_grgr_0 & 0xFF) + (row_grgr_2 & 0xFF)) >> 1;
int b2 = (((row_grgr_0 >> 16) & 0xFF) + ((row_grgr_2 >> 16) & 0xFF)) >> 1;
b_pixels_0 = (b2 << 16) | ((b0 + b2) >> 1);
#endif
break;
}
default: {
r_pixels_0 = 0;
g_pixels_0 = 0;
b_pixels_0 = 0;
break;
}
}
int y0 = ((r_pixels_0 * 38) + (g_pixels_0 * 75) + (b_pixels_0 * 15)) >> 7;
#if (OMV_JPEG_CODEC_ENABLE == 0)
y0 ^= 0x800080;
#endif
Y0[index_e] = y0, Y0[index_e + 1] = y0 >> 16;
int u0 = __SSUB16(b_pixels_0 * 64, (r_pixels_0 * 21) + (g_pixels_0 * 43)) >> 7;
#if (OMV_JPEG_CODEC_ENABLE == 1)
u0 ^= 0x800080;
#endif
CB[index_e] = u0, CB[index_e + 1] = u0 >> 16;
int v0 = __SSUB16(r_pixels_0 * 64, (g_pixels_0 * 54) + (b_pixels_0 * 10)) >> 7;
#if (OMV_JPEG_CODEC_ENABLE == 1)
v0 ^= 0x800080;
#endif
CR[index_e] = v0, CR[index_e + 1] = v0 >> 16;
int r_pixels_1, g_pixels_1, b_pixels_1;
switch (src->pixfmt) {
case PIXFORMAT_BAYER_BGGR: {
#if defined(ARM_MATH_DSP)
int row_13 = __UHADD8(row_bgbg_1, row_bgbg_3);
int row_2g = __UHADD8(row_grgr_2, __PKHBT(row_grgr_2, row_grgr_2, 16));
r_pixels_1 = __UXTB16(__UHADD8(row_grgr_2, __PKHTB(row_grgr_2, row_grgr_2, 16)));
g_pixels_1 = __UXTB16_RORn(__UHADD8(row_2g, __PKHBT(row_2g, row_13, 8)), 8);
b_pixels_1 = __UXTB16_RORn(__UHADD8(row_13, __PKHBT(row_13, row_13, 16)), 8);
#else
int r2 = (((row_grgr_2 >> 16) & 0xFF) + (row_grgr_2 & 0xFF)) >> 1;
r_pixels_1 = (row_grgr_2 & 0xFF0000) | r2;
int g1 = (row_bgbg_1 >> 16) & 0xFF;
int g2 = (((row_grgr_2 >> 24) & 0xFF) + ((row_grgr_2 >> 8) & 0xFF)) >> 1;
int g3 = (row_bgbg_3 >> 16) & 0xFF;
g_pixels_1 = (((((g1 + g3) >> 1) + g2) >> 1) << 16) | ((row_grgr_2 >> 8) & 0xFF);
int b1 = (((row_bgbg_1 >> 8) & 0xFF) + ((row_bgbg_3 >> 8) & 0xFF)) >> 1;
int b3 = (((row_bgbg_1 >> 24) & 0xFF) + ((row_bgbg_3 >> 24) & 0xFF)) >> 1;
b_pixels_1 = (((b1 + b3) >> 1) << 16) | b1;
#endif
break;
}
case PIXFORMAT_BAYER_GBRG: {
#if defined(ARM_MATH_DSP)
int row_13 = __UHADD8(row_bgbg_1, row_bgbg_3);
int row_2g = __UHADD8(row_grgr_2, __PKHTB(row_grgr_2, row_grgr_2, 16));
r_pixels_1 = __UXTB16_RORn(__UHADD8(row_grgr_2, __PKHBT(row_grgr_2, row_grgr_2, 16)), 8);
g_pixels_1 = __UXTB16(__UHADD8(row_2g, __PKHTB(row_2g, row_13, 8)));
b_pixels_1 = __UXTB16(__UHADD8(row_13, __PKHTB(row_13, row_13, 16)));
#else
int r2 = (((row_grgr_2 >> 24) & 0xFF) + ((row_grgr_2 >> 8) & 0xFF)) >> 1;
r_pixels_1 = ((row_grgr_2 >> 8) & 0xFF) | (r2 << 16);
int g1 = (row_bgbg_1 >> 8) & 0xFF;
int g2 = (((row_grgr_2 >> 16) & 0xFF) + (row_grgr_2 & 0xFF)) >> 1;
int g3 = (row_bgbg_3 >> 8) & 0xFF;
g_pixels_1 = ((((g1 + g3) >> 1) + g2) >> 1) | (row_grgr_2 & 0xFF0000);
int b1 = ((row_bgbg_1 & 0xFF) + (row_bgbg_3 & 0xFF)) >> 1;
int b3 = (((row_bgbg_1 >> 16) & 0xFF) + ((row_bgbg_3 >> 16) & 0xFF)) >> 1;
b_pixels_1 = ((b1 + b3) >> 1) | (b3 << 16);
#endif
break;
}
case PIXFORMAT_BAYER_GRBG: {
#if defined(ARM_MATH_DSP)
int row_13 = __UHADD8(row_bgbg_1, row_bgbg_3);
int row_2g = __UHADD8(row_grgr_2, __PKHTB(row_grgr_2, row_grgr_2, 16));
r_pixels_1 = __UXTB16(__UHADD8(row_13, __PKHTB(row_13, row_13, 16)));
g_pixels_1 = __UXTB16(__UHADD8(row_2g, __PKHTB(row_2g, row_13, 8)));
b_pixels_1 = __UXTB16_RORn(__UHADD8(row_grgr_2, __PKHBT(row_grgr_2, row_grgr_2, 16)), 8);
#else
int r1 = ((row_bgbg_1 & 0xFF) + (row_bgbg_3 & 0xFF)) >> 1;
int r3 = (((row_bgbg_1 >> 16) & 0xFF) + ((row_bgbg_3 >> 16) & 0xFF)) >> 1;
r_pixels_1 = ((r1 + r3) >> 1) | (r3 << 16);
int g1 = (row_bgbg_1 >> 8) & 0xFF;
int g2 = (((row_grgr_2 >> 16) & 0xFF) + (row_grgr_2 & 0xFF)) >> 1;
int g3 = (row_bgbg_3 >> 8) & 0xFF;
g_pixels_1 = ((((g1 + g3) >> 1) + g2) >> 1) | (row_grgr_2 & 0xFF0000);
int b2 = (((row_grgr_2 >> 24) & 0xFF) + ((row_grgr_2 >> 8) & 0xFF)) >> 1;
b_pixels_1 = ((row_grgr_2 >> 8) & 0xFF) | (b2 << 16);
#endif
break;
}
case PIXFORMAT_BAYER_RGGB: {
#if defined(ARM_MATH_DSP)
int row_13 = __UHADD8(row_bgbg_1, row_bgbg_3);
int row_2g = __UHADD8(row_grgr_2, __PKHBT(row_grgr_2, row_grgr_2, 16));
r_pixels_1 = __UXTB16_RORn(__UHADD8(row_13, __PKHBT(row_13, row_13, 16)), 8);
g_pixels_1 = __UXTB16_RORn(__UHADD8(row_2g, __PKHBT(row_2g, row_13, 8)), 8);
b_pixels_1 = __UXTB16(__UHADD8(row_grgr_2, __PKHTB(row_grgr_2, row_grgr_2, 16)));
#else
int r1 = (((row_bgbg_1 >> 8) & 0xFF) + ((row_bgbg_3 >> 8) & 0xFF)) >> 1;
int r3 = (((row_bgbg_1 >> 24) & 0xFF) + ((row_bgbg_3 >> 24) & 0xFF)) >> 1;
r_pixels_1 = (((r1 + r3) >> 1) << 16) | r1;
int g1 = (row_bgbg_1 >> 16) & 0xFF;
int g2 = (((row_grgr_2 >> 24) & 0xFF) + ((row_grgr_2 >> 8) & 0xFF)) >> 1;
int g3 = (row_bgbg_3 >> 16) & 0xFF;
g_pixels_1 = (((((g1 + g3) >> 1) + g2) >> 1) << 16) | ((row_grgr_2 >> 8) & 0xFF);
int b2 = (((row_grgr_2 >> 16) & 0xFF) + (row_grgr_2 & 0xFF)) >> 1;
b_pixels_1 = (row_grgr_2 & 0xFF0000) | b2;
#endif
break;
}
default: {
r_pixels_1 = 0;
g_pixels_1 = 0;
b_pixels_1 = 0;
break;
}
}
int y1 = ((r_pixels_1 * 38) + (g_pixels_1 * 75) + (b_pixels_1 * 15)) >> 7;
#if (OMV_JPEG_CODEC_ENABLE == 0)
y1 ^= 0x800080;
#endif
Y0[index_o] = y1, Y0[index_o + 1] = y1 >> 16;
int u1 = __SSUB16(b_pixels_1 * 64, (r_pixels_1 * 21) + (g_pixels_1 * 43)) >> 7;
#if (OMV_JPEG_CODEC_ENABLE == 1)
u1 ^= 0x800080;
#endif
CB[index_o] = u1, CB[index_o + 1] = u1 >> 16;
int v1 = __SSUB16(r_pixels_1 * 64, (g_pixels_1 * 54) + (b_pixels_1 * 10)) >> 7;
#if (OMV_JPEG_CODEC_ENABLE == 1)
v1 ^= 0x800080;
#endif
CR[index_o] = v1, CR[index_o + 1] = v1 >> 16;
}
}
} else {
// If dy is odd this loop will produce 1 extra boundary row in the MCU.
// This is okay given the boundary checking code below.
for (int y = y_offset, yy = y + dy, index_e = 0, index_o = JPEG_MCU_W; y < yy; y += 2) {
uint8_t *rowptr_grgr_0, *rowptr_bgbg_1, *rowptr_grgr_2, *rowptr_bgbg_3;
// keep row pointers in bounds
if (y == 0) {
rowptr_bgbg_1 = src->data;
rowptr_grgr_2 = rowptr_bgbg_1 + ((src_h >= 2) ? src_w : 0);
rowptr_bgbg_3 = rowptr_bgbg_1 + ((src_h >= 3) ? (src_w * 2) : 0);
rowptr_grgr_0 = rowptr_grgr_2;
} else if (y == h_limit_m_1) {
rowptr_grgr_0 = src->data + ((y - 1) * src_w);
rowptr_bgbg_1 = rowptr_grgr_0 + src_w;
rowptr_grgr_2 = rowptr_bgbg_1 + src_w;
rowptr_bgbg_3 = rowptr_bgbg_1;
} else if (y >= h_limit) {
rowptr_grgr_0 = src->data + ((y - 1) * src_w);
rowptr_bgbg_1 = rowptr_grgr_0 + src_w;
rowptr_grgr_2 = rowptr_grgr_0;
rowptr_bgbg_3 = rowptr_bgbg_1;
} else {
// get 4 neighboring rows
rowptr_grgr_0 = src->data + ((y - 1) * src_w);
rowptr_bgbg_1 = rowptr_grgr_0 + src_w;
rowptr_grgr_2 = rowptr_bgbg_1 + src_w;
rowptr_bgbg_3 = rowptr_grgr_2 + src_w;
}
// If dx is odd this loop will produce 1 extra boundary column in the MCU.
// This is okay given the boundary checking code below.
for (int x = x_offset, xx = x + dx; x < xx; x += 2, index_e += 2, index_o += 2) {
uint32_t row_grgr_0, row_bgbg_1, row_grgr_2, row_bgbg_3;
// keep pixels in bounds
if (x == 0) {
if (src_w >= 4) {
row_grgr_0 = *((uint32_t *) rowptr_grgr_0);
row_bgbg_1 = *((uint32_t *) rowptr_bgbg_1);
row_grgr_2 = *((uint32_t *) rowptr_grgr_2);
row_bgbg_3 = *((uint32_t *) rowptr_bgbg_3);
} else if (src_w >= 3) {
row_grgr_0 = *((uint16_t *) rowptr_grgr_0) | (*(rowptr_grgr_0 + 2) << 16);
row_bgbg_1 = *((uint16_t *) rowptr_bgbg_1) | (*(rowptr_bgbg_1 + 2) << 16);
row_grgr_2 = *((uint16_t *) rowptr_grgr_2) | (*(rowptr_grgr_2 + 2) << 16);
row_bgbg_3 = *((uint16_t *) rowptr_bgbg_3) | (*(rowptr_bgbg_3 + 2) << 16);
} else if (src_w >= 2) {
row_grgr_0 = *((uint16_t *) rowptr_grgr_0);
row_grgr_0 = (row_grgr_0 << 16) | row_grgr_0;
row_bgbg_1 = *((uint16_t *) rowptr_bgbg_1);
row_bgbg_1 = (row_bgbg_1 << 16) | row_bgbg_1;
row_grgr_2 = *((uint16_t *) rowptr_grgr_2);
row_grgr_2 = (row_grgr_2 << 16) | row_grgr_2;
row_bgbg_3 = *((uint16_t *) rowptr_bgbg_3);
row_bgbg_3 = (row_bgbg_3 << 16) | row_bgbg_3;
} else {
row_grgr_0 = *(rowptr_grgr_0) * 0x01010101;
row_bgbg_1 = *(rowptr_bgbg_1) * 0x01010101;
row_grgr_2 = *(rowptr_grgr_2) * 0x01010101;
row_bgbg_3 = *(rowptr_bgbg_3) * 0x01010101;
}
// The starting point needs to be offset by 1. The below patterns are actually
// rgrg, gbgb, rgrg, and gbgb. So, shift left and backfill the missing border pixel.
row_grgr_0 = (row_grgr_0 << 8) | __UXTB_RORn(row_grgr_0, 8);
row_bgbg_1 = (row_bgbg_1 << 8) | __UXTB_RORn(row_bgbg_1, 8);
row_grgr_2 = (row_grgr_2 << 8) | __UXTB_RORn(row_grgr_2, 8);
row_bgbg_3 = (row_bgbg_3 << 8) | __UXTB_RORn(row_bgbg_3, 8);
} else if (x == w_limit_m_1) {
row_grgr_0 = *((uint32_t *) (rowptr_grgr_0 + x - 2));
row_grgr_0 = (row_grgr_0 >> 8) | ((row_grgr_0 << 8) & 0xff000000);
row_bgbg_1 = *((uint32_t *) (rowptr_bgbg_1 + x - 2));
row_bgbg_1 = (row_bgbg_1 >> 8) | ((row_bgbg_1 << 8) & 0xff000000);
row_grgr_2 = *((uint32_t *) (rowptr_grgr_2 + x - 2));
row_grgr_2 = (row_grgr_2 >> 8) | ((row_grgr_2 << 8) & 0xff000000);
row_bgbg_3 = *((uint32_t *) (rowptr_bgbg_3 + x - 2));
row_bgbg_3 = (row_bgbg_3 >> 8) | ((row_bgbg_1 << 8) & 0xff000000);
} else if (x >= w_limit) {
row_grgr_0 = *((uint16_t *) (rowptr_grgr_0 + x - 1));
row_grgr_0 = (row_grgr_0 << 16) | row_grgr_0;
row_bgbg_1 = *((uint16_t *) (rowptr_bgbg_1 + x - 1));
row_bgbg_1 = (row_bgbg_1 << 16) | row_bgbg_1;
row_grgr_2 = *((uint16_t *) (rowptr_grgr_2 + x - 1));
row_grgr_2 = (row_grgr_2 << 16) | row_grgr_2;
row_bgbg_3 = *((uint16_t *) (rowptr_bgbg_3 + x - 1));
row_bgbg_3 = (row_bgbg_3 << 16) | row_bgbg_3;
} else {
// get 4 neighboring rows
row_grgr_0 = *((uint32_t *) (rowptr_grgr_0 + x - 1));
row_bgbg_1 = *((uint32_t *) (rowptr_bgbg_1 + x - 1));
row_grgr_2 = *((uint32_t *) (rowptr_grgr_2 + x - 1));
row_bgbg_3 = *((uint32_t *) (rowptr_bgbg_3 + x - 1));
}
int r_pixels_0, g_pixels_0, b_pixels_0;
switch (src->pixfmt) {
case PIXFORMAT_BAYER_BGGR: {
#if defined(ARM_MATH_DSP)
int row_02 = __UHADD8(row_grgr_0, row_grgr_2);
int row_1g = __UHADD8(row_bgbg_1, __PKHTB(row_bgbg_1, row_bgbg_1, 16));
r_pixels_0 = __UXTB16(__UHADD8(row_02, __PKHTB(row_02, row_02, 16)));
g_pixels_0 = __UXTB16(__UHADD8(row_1g, __PKHTB(row_1g, row_02, 8)));
b_pixels_0 = __UXTB16_RORn(__UHADD8(row_bgbg_1, __PKHBT(row_bgbg_1, row_bgbg_1, 16)), 8);
#else
int r0 = ((row_grgr_0 & 0xFF) + (row_grgr_2 & 0xFF)) >> 1;
int r2 = (((row_grgr_0 >> 16) & 0xFF) + ((row_grgr_2 >> 16) & 0xFF)) >> 1;
r_pixels_0 = (r2 << 16) | ((r0 + r2) >> 1);
int g0 = (row_grgr_0 >> 8) & 0xFF;
int g1 = (((row_bgbg_1 >> 16) & 0xFF) + (row_bgbg_1 & 0xFF)) >> 1;
int g2 = (row_grgr_2 >> 8) & 0xFF;
g_pixels_0 = (row_bgbg_1 & 0xFF0000) | ((((g0 + g2) >> 1) + g1) >> 1);
int b1 = (((row_bgbg_1 >> 24) & 0xFF) + ((row_bgbg_1 >> 8) & 0xFF)) >> 1;
b_pixels_0 = (b1 << 16) | ((row_bgbg_1 >> 8) & 0xFF);
#endif
break;
}
case PIXFORMAT_BAYER_GBRG: {
#if defined(ARM_MATH_DSP)
int row_02 = __UHADD8(row_grgr_0, row_grgr_2);
int row_1g = __UHADD8(row_bgbg_1, __PKHBT(row_bgbg_1, row_bgbg_1, 16));
r_pixels_0 = __UXTB16_RORn(__UHADD8(row_02, __PKHBT(row_02, row_02, 16)), 8);
g_pixels_0 = __UXTB16_RORn(__UHADD8(row_1g, __PKHBT(row_1g, row_02, 8)), 8);
b_pixels_0 = __UXTB16(__UHADD8(row_bgbg_1, __PKHTB(row_bgbg_1, row_bgbg_1, 16)));
#else
int r0 = (((row_grgr_0 >> 8) & 0xFF) + ((row_grgr_2 >> 8) & 0xFF)) >> 1;
int r2 = (((row_grgr_0 >> 24) & 0xFF) + ((row_grgr_2 >> 24) & 0xFF)) >> 1;
r_pixels_0 = r0 | (((r0 + r2) >> 1) << 16);
int g0 = (row_grgr_0 >> 16) & 0xFF;
int g1 = (((row_bgbg_1 >> 24) & 0xFF) + ((row_bgbg_1 >> 8) & 0xFF)) >> 1;
int g2 = (row_grgr_2 >> 16) & 0xFF;
g_pixels_0 = ((row_bgbg_1 >> 8) & 0xFF) | (((((g0 + g2) >> 1) + g1) >> 1) << 16);
int b1 = (((row_bgbg_1 >> 16) & 0xFF) + (row_bgbg_1 & 0xFF)) >> 1;
b_pixels_0 = b1 | (row_bgbg_1 & 0xFF0000);
#endif
break;
}
case PIXFORMAT_BAYER_GRBG: {
#if defined(ARM_MATH_DSP)
int row_02 = __UHADD8(row_grgr_0, row_grgr_2);
int row_1g = __UHADD8(row_bgbg_1, __PKHBT(row_bgbg_1, row_bgbg_1, 16));
r_pixels_0 = __UXTB16(__UHADD8(row_bgbg_1, __PKHTB(row_bgbg_1, row_bgbg_1, 16)));
g_pixels_0 = __UXTB16_RORn(__UHADD8(row_1g, __PKHBT(row_1g, row_02, 8)), 8);
b_pixels_0 = __UXTB16_RORn(__UHADD8(row_02, __PKHBT(row_02, row_02, 16)), 8);
#else
int r1 = (((row_bgbg_1 >> 16) & 0xFF) + (row_bgbg_1 & 0xFF)) >> 1;
r_pixels_0 = r1 | (row_bgbg_1 & 0xFF0000);
int g0 = (row_grgr_0 >> 16) & 0xFF;
int g1 = (((row_bgbg_1 >> 24) & 0xFF) + ((row_bgbg_1 >> 8) & 0xFF)) >> 1;
int g2 = (row_grgr_2 >> 16) & 0xFF;
g_pixels_0 = ((row_bgbg_1 >> 8) & 0xFF) | (((((g0 + g2) >> 1) + g1) >> 1) << 16);
int b0 = (((row_grgr_0 >> 8) & 0xFF) + ((row_grgr_2 >> 8) & 0xFF)) >> 1;
int b2 = (((row_grgr_0 >> 24) & 0xFF) + ((row_grgr_2 >> 24) & 0xFF)) >> 1;
b_pixels_0 = b0 | (((b0 + b2) >> 1) << 16);
#endif
break;
}
case PIXFORMAT_BAYER_RGGB: {
#if defined(ARM_MATH_DSP)
int row_02 = __UHADD8(row_grgr_0, row_grgr_2);
int row_1g = __UHADD8(row_bgbg_1, __PKHTB(row_bgbg_1, row_bgbg_1, 16));
r_pixels_0 = __UXTB16_RORn(__UHADD8(row_bgbg_1, __PKHBT(row_bgbg_1, row_bgbg_1, 16)), 8);
g_pixels_0 = __UXTB16(__UHADD8(row_1g, __PKHTB(row_1g, row_02, 8)));
b_pixels_0 = __UXTB16(__UHADD8(row_02, __PKHTB(row_02, row_02, 16)));
#else
int r1 = (((row_bgbg_1 >> 24) & 0xFF) + ((row_bgbg_1 >> 8) & 0xFF)) >> 1;
r_pixels_0 = (r1 << 16) | ((row_bgbg_1 >> 8) & 0xFF);
int g0 = (row_grgr_0 >> 8) & 0xFF;
int g1 = (((row_bgbg_1 >> 16) & 0xFF) + (row_bgbg_1 & 0xFF)) >> 1;
int g2 = (row_grgr_2 >> 8) & 0xFF;
g_pixels_0 = (row_bgbg_1 & 0xFF0000) | ((((g0 + g2) >> 1) + g1) >> 1);
int b0 = ((row_grgr_0 & 0xFF) + (row_grgr_2 & 0xFF)) >> 1;
int b2 = (((row_grgr_0 >> 16) & 0xFF) + ((row_grgr_2 >> 16) & 0xFF)) >> 1;
b_pixels_0 = (b2 << 16) | ((b0 + b2) >> 1);
#endif
break;
}
default: {
r_pixels_0 = 0;
g_pixels_0 = 0;
b_pixels_0 = 0;
break;
}
}
int y0 = ((r_pixels_0 * 38) + (g_pixels_0 * 75) + (b_pixels_0 * 15)) >> 7;
#if (OMV_JPEG_CODEC_ENABLE == 0)
y0 ^= 0x800080;
#endif
Y0[index_e] = y0, Y0[index_e + 1] = y0 >> 16;
int u0 = __SSUB16(b_pixels_0 * 64, (r_pixels_0 * 21) + (g_pixels_0 * 43)) >> 7;
#if (OMV_JPEG_CODEC_ENABLE == 1)
u0 ^= 0x800080;
#endif
CB[index_e] = u0, CB[index_e + 1] = u0 >> 16;
int v0 = __SSUB16(r_pixels_0 * 64, (g_pixels_0 * 54) + (b_pixels_0 * 10)) >> 7;
#if (OMV_JPEG_CODEC_ENABLE == 1)
v0 ^= 0x800080;
#endif
CR[index_e] = v0, CR[index_e + 1] = v0 >> 16;
int r_pixels_1, g_pixels_1, b_pixels_1;
switch (src->pixfmt) {
case PIXFORMAT_BAYER_BGGR: {
#if defined(ARM_MATH_DSP)
int row_13 = __UHADD8(row_bgbg_1, row_bgbg_3);
int row_2g = __UHADD8(row_grgr_2, __PKHBT(row_grgr_2, row_grgr_2, 16));
r_pixels_1 = __UXTB16(__UHADD8(row_grgr_2, __PKHTB(row_grgr_2, row_grgr_2, 16)));
g_pixels_1 = __UXTB16_RORn(__UHADD8(row_2g, __PKHBT(row_2g, row_13, 8)), 8);
b_pixels_1 = __UXTB16_RORn(__UHADD8(row_13, __PKHBT(row_13, row_13, 16)), 8);
#else
int r2 = (((row_grgr_2 >> 16) & 0xFF) + (row_grgr_2 & 0xFF)) >> 1;
r_pixels_1 = (row_grgr_2 & 0xFF0000) | r2;
int g1 = (row_bgbg_1 >> 16) & 0xFF;
int g2 = (((row_grgr_2 >> 24) & 0xFF) + ((row_grgr_2 >> 8) & 0xFF)) >> 1;
int g3 = (row_bgbg_3 >> 16) & 0xFF;
g_pixels_1 = (((((g1 + g3) >> 1) + g2) >> 1) << 16) | ((row_grgr_2 >> 8) & 0xFF);
int b1 = (((row_bgbg_1 >> 8) & 0xFF) + ((row_bgbg_3 >> 8) & 0xFF)) >> 1;
int b3 = (((row_bgbg_1 >> 24) & 0xFF) + ((row_bgbg_3 >> 24) & 0xFF)) >> 1;
b_pixels_1 = (((b1 + b3) >> 1) << 16) | b1;
#endif
break;
}
case PIXFORMAT_BAYER_GBRG: {
#if defined(ARM_MATH_DSP)
int row_13 = __UHADD8(row_bgbg_1, row_bgbg_3);
int row_2g = __UHADD8(row_grgr_2, __PKHTB(row_grgr_2, row_grgr_2, 16));
r_pixels_1 = __UXTB16_RORn(__UHADD8(row_grgr_2, __PKHBT(row_grgr_2, row_grgr_2, 16)), 8);
g_pixels_1 = __UXTB16(__UHADD8(row_2g, __PKHTB(row_2g, row_13, 8)));
b_pixels_1 = __UXTB16(__UHADD8(row_13, __PKHTB(row_13, row_13, 16)));
#else
int r2 = (((row_grgr_2 >> 24) & 0xFF) + ((row_grgr_2 >> 8) & 0xFF)) >> 1;
r_pixels_1 = ((row_grgr_2 >> 8) & 0xFF) | (r2 << 16);
int g1 = (row_bgbg_1 >> 8) & 0xFF;
int g2 = (((row_grgr_2 >> 16) & 0xFF) + (row_grgr_2 & 0xFF)) >> 1;
int g3 = (row_bgbg_3 >> 8) & 0xFF;
g_pixels_1 = ((((g1 + g3) >> 1) + g2) >> 1) | (row_grgr_2 & 0xFF0000);
int b1 = ((row_bgbg_1 & 0xFF) + (row_bgbg_3 & 0xFF)) >> 1;
int b3 = (((row_bgbg_1 >> 16) & 0xFF) + ((row_bgbg_3 >> 16) & 0xFF)) >> 1;
b_pixels_1 = ((b1 + b3) >> 1) | (b3 << 16);
#endif
break;
}
case PIXFORMAT_BAYER_GRBG: {
#if defined(ARM_MATH_DSP)
int row_13 = __UHADD8(row_bgbg_1, row_bgbg_3);
int row_2g = __UHADD8(row_grgr_2, __PKHTB(row_grgr_2, row_grgr_2, 16));
r_pixels_1 = __UXTB16(__UHADD8(row_13, __PKHTB(row_13, row_13, 16)));
g_pixels_1 = __UXTB16(__UHADD8(row_2g, __PKHTB(row_2g, row_13, 8)));
b_pixels_1 = __UXTB16_RORn(__UHADD8(row_grgr_2, __PKHBT(row_grgr_2, row_grgr_2, 16)), 8);
#else
int r1 = ((row_bgbg_1 & 0xFF) + (row_bgbg_3 & 0xFF)) >> 1;
int r3 = (((row_bgbg_1 >> 16) & 0xFF) + ((row_bgbg_3 >> 16) & 0xFF)) >> 1;
r_pixels_1 = ((r1 + r3) >> 1) | (r3 << 16);
int g1 = (row_bgbg_1 >> 8) & 0xFF;
int g2 = (((row_grgr_2 >> 16) & 0xFF) + (row_grgr_2 & 0xFF)) >> 1;
int g3 = (row_bgbg_3 >> 8) & 0xFF;
g_pixels_1 = ((((g1 + g3) >> 1) + g2) >> 1) | (row_grgr_2 & 0xFF0000);
int b2 = (((row_grgr_2 >> 24) & 0xFF) + ((row_grgr_2 >> 8) & 0xFF)) >> 1;
b_pixels_1 = ((row_grgr_2 >> 8) & 0xFF) | (b2 << 16);
#endif
break;
}
case PIXFORMAT_BAYER_RGGB: {
#if defined(ARM_MATH_DSP)
int row_13 = __UHADD8(row_bgbg_1, row_bgbg_3);
int row_2g = __UHADD8(row_grgr_2, __PKHBT(row_grgr_2, row_grgr_2, 16));
r_pixels_1 = __UXTB16_RORn(__UHADD8(row_13, __PKHBT(row_13, row_13, 16)), 8);
g_pixels_1 = __UXTB16_RORn(__UHADD8(row_2g, __PKHBT(row_2g, row_13, 8)), 8);
b_pixels_1 = __UXTB16(__UHADD8(row_grgr_2, __PKHTB(row_grgr_2, row_grgr_2, 16)));
#else
int r1 = (((row_bgbg_1 >> 8) & 0xFF) + ((row_bgbg_3 >> 8) & 0xFF)) >> 1;
int r3 = (((row_bgbg_1 >> 24) & 0xFF) + ((row_bgbg_3 >> 24) & 0xFF)) >> 1;
r_pixels_1 = (((r1 + r3) >> 1) << 16) | r1;
int g1 = (row_bgbg_1 >> 16) & 0xFF;
int g2 = (((row_grgr_2 >> 24) & 0xFF) + ((row_grgr_2 >> 8) & 0xFF)) >> 1;
int g3 = (row_bgbg_3 >> 16) & 0xFF;
g_pixels_1 = (((((g1 + g3) >> 1) + g2) >> 1) << 16) | ((row_grgr_2 >> 8) & 0xFF);
int b2 = (((row_grgr_2 >> 16) & 0xFF) + (row_grgr_2 & 0xFF)) >> 1;
b_pixels_1 = (row_grgr_2 & 0xFF0000) | b2;
#endif
break;
}
default: {
r_pixels_1 = 0;
g_pixels_1 = 0;
b_pixels_1 = 0;
break;
}
}
int y1 = ((r_pixels_1 * 38) + (g_pixels_1 * 75) + (b_pixels_1 * 15)) >> 7;
#if (OMV_JPEG_CODEC_ENABLE == 0)
y1 ^= 0x800080;
#endif
Y0[index_o] = y1, Y0[index_o + 1] = y1 >> 16;
int u1 = __SSUB16(b_pixels_1 * 64, (r_pixels_1 * 21) + (g_pixels_1 * 43)) >> 7;
#if (OMV_JPEG_CODEC_ENABLE == 1)
u1 ^= 0x800080;
#endif
CB[index_o] = u1, CB[index_o + 1] = u1 >> 16;
int v1 = __SSUB16(r_pixels_1 * 64, (g_pixels_1 * 54) + (b_pixels_1 * 10)) >> 7;
#if (OMV_JPEG_CODEC_ENABLE == 1)
v1 ^= 0x800080;
#endif
CR[index_o] = v1, CR[index_o + 1] = v1 >> 16;
}
int inc = (JPEG_MCU_W * 2) - (((dx + 1) / 2) * 2); // Handle boundary column.
index_e += inc;
index_o += inc;
}
}
rectangle_t roi = {
.x = x_offset,
.y = y_offset,
.w = dx,
.h = dy
};
imlib_debayer_ycbcr(src, &roi, Y0, CB, CR);
break;
}
}

1781
src/omv/imlib/simd.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -684,7 +684,7 @@ int ov7725_init(sensor_t *sensor) {
sensor->rgb_swap = 1;
sensor->blc_size = 8;
sensor->yuv_format = SUBFORMAT_ID_YVU422;
sensor->cfa_format = SUBFORMAT_ID_GBRG;
sensor->cfa_format = SUBFORMAT_ID_BGGR;
return 0;
}