📄 colorspace.c
字号:
#define FIX_OUT(x) ((uint16_t) ((x) * (1L<<SCALEBITS_OUT) + 0.5))/* initialize rgb lookup tables */voidcolorspace_init(void){ int32_t i; for (i = 0; i < 256; i++) { RGB_Y_tab[i] = FIX_OUT(RGB_Y_OUT) * (i - Y_ADD_OUT); B_U_tab[i] = FIX_OUT(B_U_OUT) * (i - U_ADD_OUT); G_U_tab[i] = FIX_OUT(G_U_OUT) * (i - U_ADD_OUT); G_V_tab[i] = FIX_OUT(G_V_OUT) * (i - V_ADD_OUT); R_V_tab[i] = FIX_OUT(R_V_OUT) * (i - V_ADD_OUT); }}/* yuv 4:2:0 planar -> rgb555 + very simple error diffusion*/#define MK_RGB555(R,G,B) ((MAX(0,MIN(255, R)) << 7) & 0x7c00) | \ ((MAX(0,MIN(255, G)) << 2) & 0x03e0) | \ ((MAX(0,MIN(255, B)) >> 3) & 0x001f)voidyv12_to_rgb555_c(uint8_t * dst, int dst_stride, uint8_t * y_src, uint8_t * u_src, uint8_t * v_src, int y_stride, int uv_stride, int width, int height){ const uint32_t dst_dif = 4 * dst_stride - 2 * width; int32_t y_dif = 2 * y_stride - width; uint8_t *dst2 = dst + 2 * dst_stride; uint8_t *y_src2 = y_src + y_stride; uint32_t x, y; if (height < 0) { height = -height; y_src += (height - 1) * y_stride; y_src2 = y_src - y_stride; u_src += (height / 2 - 1) * uv_stride; v_src += (height / 2 - 1) * uv_stride; y_dif = -width - 2 * y_stride; uv_stride = -uv_stride; } for (y = height / 2; y; y--) { int r, g, b; int r2, g2, b2; r = g = b = 0; r2 = g2 = b2 = 0; /* process one 2x2 block per iteration */ for (x = 0; x < (uint32_t) width / 2; x++) { int u, v; int b_u, g_uv, r_v, rgb_y; u = u_src[x]; v = v_src[x]; b_u = B_U_tab[u]; g_uv = G_U_tab[u] + G_V_tab[v]; r_v = R_V_tab[v]; rgb_y = RGB_Y_tab[*y_src]; b = (b & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); g = (g & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); r = (r & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); *(uint16_t *) dst = MK_RGB555(r, g, b); y_src++; rgb_y = RGB_Y_tab[*y_src]; b = (b & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); g = (g & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); r = (r & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); *(uint16_t *) (dst + 2) = MK_RGB555(r, g, b); y_src++; rgb_y = RGB_Y_tab[*y_src2]; b2 = (b2 & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); g2 = (g2 & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); r2 = (r2 & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); *(uint16_t *) (dst2) = MK_RGB555(r2, g2, b2); y_src2++; rgb_y = RGB_Y_tab[*y_src2]; b2 = (b2 & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); g2 = (g2 & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); r2 = (r2 & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); *(uint16_t *) (dst2 + 2) = MK_RGB555(r2, g2, b2); y_src2++; dst += 4; dst2 += 4; } dst += dst_dif; dst2 += dst_dif; y_src += y_dif; y_src2 += y_dif; u_src += uv_stride; v_src += uv_stride; }}/* yuv 4:2:0 planar -> rgb565 + very simple error diffusion NOTE: identical to rgb555 except for shift/mask */#define MK_RGB565(R,G,B) ((MAX(0,MIN(255, R)) << 8) & 0xf800) | \ ((MAX(0,MIN(255, G)) << 3) & 0x07e0) | \ ((MAX(0,MIN(255, B)) >> 3) & 0x001f)voidyv12_to_rgb565_c(uint8_t * dst, int dst_stride, uint8_t * y_src, uint8_t * u_src, uint8_t * v_src, int y_stride, int uv_stride, int width, int height){ const uint32_t dst_dif = 4 * dst_stride - 2 * width; int32_t y_dif = 2 * y_stride - width; uint8_t *dst2 = dst + 2 * dst_stride; uint8_t *y_src2 = y_src + y_stride; uint32_t x, y; if (height < 0) { /* flip image? */ height = -height; y_src += (height - 1) * y_stride; y_src2 = y_src - y_stride; u_src += (height / 2 - 1) * uv_stride; v_src += (height / 2 - 1) * uv_stride; y_dif = -width - 2 * y_stride; uv_stride = -uv_stride; } for (y = height / 2; y; y--) { int r, g, b; int r2, g2, b2; r = g = b = 0; r2 = g2 = b2 = 0; /* process one 2x2 block per iteration */ for (x = 0; x < (uint32_t) width / 2; x++) { int u, v; int b_u, g_uv, r_v, rgb_y; u = u_src[x]; v = v_src[x]; b_u = B_U_tab[u]; g_uv = G_U_tab[u] + G_V_tab[v]; r_v = R_V_tab[v]; rgb_y = RGB_Y_tab[*y_src]; b = (b & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); g = (g & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); r = (r & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); *(uint16_t *) dst = MK_RGB565(r, g, b); y_src++; rgb_y = RGB_Y_tab[*y_src]; b = (b & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); g = (g & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); r = (r & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); *(uint16_t *) (dst + 2) = MK_RGB565(r, g, b); y_src++; rgb_y = RGB_Y_tab[*y_src2]; b2 = (b2 & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); g2 = (g2 & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); r2 = (r2 & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); *(uint16_t *) (dst2) = MK_RGB565(r2, g2, b2); y_src2++; rgb_y = RGB_Y_tab[*y_src2]; b2 = (b2 & 0x7) + ((rgb_y + b_u) >> SCALEBITS_OUT); g2 = (g2 & 0x7) + ((rgb_y - g_uv) >> SCALEBITS_OUT); r2 = (r2 & 0x7) + ((rgb_y + r_v) >> SCALEBITS_OUT); *(uint16_t *) (dst2 + 2) = MK_RGB565(r2, g2, b2); y_src2++; dst += 4; dst2 += 4; } dst += dst_dif; dst2 += dst_dif; y_src += y_dif; y_src2 += y_dif; u_src += uv_stride; v_src += uv_stride; }}/* yuv 4:2:0 planar -> rgb24 */voidyv12_to_rgb24_c(uint8_t * dst, int dst_stride, uint8_t * y_src, uint8_t * u_src, uint8_t * v_src, int y_stride, int uv_stride, int width, int height){ const uint32_t dst_dif = 6 * dst_stride - 3 * width; int32_t y_dif = 2 * y_stride - width; uint8_t *dst2 = dst + 3 * dst_stride; uint8_t *y_src2 = y_src + y_stride; uint32_t x, y; if (height < 0) { /* flip image? */ height = -height; y_src += (height - 1) * y_stride; y_src2 = y_src - y_stride; u_src += (height / 2 - 1) * uv_stride; v_src += (height / 2 - 1) * uv_stride; y_dif = -width - 2 * y_stride; uv_stride = -uv_stride; } for (y = height / 2; y; y--) { /* process one 2x2 block per iteration */ for (x = 0; x < (uint32_t) width / 2; x++) { int u, v; int b_u, g_uv, r_v, rgb_y; int r, g, b; u = u_src[x]; v = v_src[x]; b_u = B_U_tab[u]; g_uv = G_U_tab[u] + G_V_tab[v]; r_v = R_V_tab[v]; rgb_y = RGB_Y_tab[*y_src]; b = (rgb_y + b_u) >> SCALEBITS_OUT; g = (rgb_y - g_uv) >> SCALEBITS_OUT; r = (rgb_y + r_v) >> SCALEBITS_OUT; dst[0] = MAX(0, MIN(255, b)); dst[1] = MAX(0, MIN(255, g)); dst[2] = MAX(0, MIN(255, r)); y_src++; rgb_y = RGB_Y_tab[*y_src]; b = (rgb_y + b_u) >> SCALEBITS_OUT; g = (rgb_y - g_uv) >> SCALEBITS_OUT; r = (rgb_y + r_v) >> SCALEBITS_OUT; dst[3] = MAX(0, MIN(255, b)); dst[4] = MAX(0, MIN(255, g)); dst[5] = MAX(0, MIN(255, r)); y_src++; rgb_y = RGB_Y_tab[*y_src2]; b = (rgb_y + b_u) >> SCALEBITS_OUT; g = (rgb_y - g_uv) >> SCALEBITS_OUT; r = (rgb_y + r_v) >> SCALEBITS_OUT; dst2[0] = MAX(0, MIN(255, b)); dst2[1] = MAX(0, MIN(255, g)); dst2[2] = MAX(0, MIN(255, r)); y_src2++; rgb_y = RGB_Y_tab[*y_src2]; b = (rgb_y + b_u) >> SCALEBITS_OUT; g = (rgb_y - g_uv) >> SCALEBITS_OUT; r = (rgb_y + r_v) >> SCALEBITS_OUT; dst2[3] = MAX(0, MIN(255, b)); dst2[4] = MAX(0, MIN(255, g)); dst2[5] = MAX(0, MIN(255, r)); y_src2++; dst += 6; dst2 += 6; } dst += dst_dif; dst2 += dst_dif; y_src += y_dif; y_src2 += y_dif; u_src += uv_stride; v_src += uv_stride; }}/* yuv 4:2:0 planar -> rgb32 */voidyv12_to_rgb32_c(uint8_t * dst, int dst_stride, uint8_t * y_src, uint8_t * v_src, uint8_t * u_src, int y_stride, int uv_stride, int width, int height){ const uint32_t dst_dif = 8 * dst_stride - 4 * width; int32_t y_dif = 2 * y_stride - width; uint8_t *dst2 = dst + 4 * dst_stride; uint8_t *y_src2 = y_src + y_stride; uint32_t x, y; if (height < 0) { /* flip image? */ height = -height; y_src += (height - 1) * y_stride; y_src2 = y_src - y_stride; u_src += (height / 2 - 1) * uv_stride; v_src += (height / 2 - 1) * uv_stride; y_dif = -width - 2 * y_stride; uv_stride = -uv_stride; } for (y = height / 2; y; y--) { /* process one 2x2 block per iteration */ for (x = 0; x < (uint32_t) width / 2; x++) { int u, v; int b_u, g_uv, r_v, rgb_y; int r, g, b; u = u_src[x]; v = v_src[x]; b_u = B_U_tab[u]; g_uv = G_U_tab[u] + G_V_tab[v]; r_v = R_V_tab[v]; rgb_y = RGB_Y_tab[*y_src]; b = (rgb_y + b_u) >> SCALEBITS_OUT; g = (rgb_y - g_uv) >> SCALEBITS_OUT; r = (rgb_y + r_v) >> SCALEBITS_OUT; dst[0] = MAX(0, MIN(255, r)); dst[1] = MAX(0, MIN(255, g)); dst[2] = MAX(0, MIN(255, b)); dst[3] = 0; y_src++; rgb_y = RGB_Y_tab[*y_src]; b = (rgb_y + b_u) >> SCALEBITS_OUT; g = (rgb_y - g_uv) >> SCALEBITS_OUT; r = (rgb_y + r_v) >> SCALEBITS_OUT; dst[4] = MAX(0, MIN(255, r)); dst[5] = MAX(0, MIN(255, g)); dst[6] = MAX(0, MIN(255, b)); dst[7] = 0; y_src++; rgb_y = RGB_Y_tab[*y_src2]; b = (rgb_y + b_u) >> SCALEBITS_OUT; g = (rgb_y - g_uv) >> SCALEBITS_OUT; r = (rgb_y + r_v) >> SCALEBITS_OUT; dst2[0] = MAX(0, MIN(255, r)); dst2[1] = MAX(0, MIN(255, g)); dst2[2] = MAX(0, MIN(255, b)); dst2[3] = 0; y_src2++; rgb_y = RGB_Y_tab[*y_src2]; b = (rgb_y + b_u) >> SCALEBITS_OUT; g = (rgb_y - g_uv) >> SCALEBITS_OUT; r = (rgb_y + r_v) >> SCALEBITS_OUT; dst2[4] = MAX(0, MIN(255, r)); dst2[5] = MAX(0, MIN(255, g)); dst2[6] = MAX(0, MIN(255, b)); dst2[7] = 0; y_src2++; dst += 8; dst2 += 8; } dst += dst_dif; dst2 += dst_dif; y_src += y_dif; y_src2 += y_dif; u_src += uv_stride; v_src += uv_stride; }}/* yuv 4:2:0 planar -> yuv planar */voidyv12_to_yuv_c(uint8_t * dst, int dst_stride, uint8_t * y_src, uint8_t * u_src, uint8_t * v_src, int y_stride, int uv_stride, int width, int height){ uint32_t dst_stride2 = dst_stride >> 1; uint32_t width2 = width >> 1; uint32_t y; if (height < 0) { height = -height; y_src += (height - 1) * y_stride; u_src += (height / 2 - 1) * uv_stride; v_src += (height / 2 - 1) * uv_stride; y_stride = -y_stride; uv_stride = -uv_stride; } for (y = height; y; y--) { memcpy(dst, y_src, width); dst += dst_stride; y_src += y_stride; } for (y = height >> 1; y; y--) { memcpy(dst, u_src, width2); dst += dst_stride2; u_src += uv_stride; } for (y = height >> 1; y; y--) { memcpy(dst, v_src, width2); dst += dst_stride2; v_src += uv_stride; }}/* yuv 4:2:0 planar -> yuyv (yuv2) packed */voidyv12_to_yuyv_c(uint8_t * dst, int dst_stride, uint8_t * y_src, uint8_t * u_src, uint8_t * v_src, int y_stride, int uv_stride, int width, int height){ const uint32_t dst_dif = 2 * (dst_stride - width); uint32_t x, y; if (height < 0) { height = -height; y_src += (height - 1) * y_stride; u_src += (height / 2 - 1) * uv_stride; v_src += (height / 2 - 1) * uv_stride; y_stride = -y_stride; uv_stride = -uv_stride; } for (y = 0; y < (uint32_t) height; y++) { for (x = 0; x < (uint32_t) width / 2; x++) { dst[0] = y_src[2 * x]; dst[1] = u_src[x]; dst[2] = y_src[2 * x + 1]; dst[3] = v_src[x]; dst += 4; } dst += dst_dif; y_src += y_stride; if (y & 1) { u_src += uv_stride; v_src += uv_stride; } }}/* yuv 4:2:0 planar -> uyvy packed */voidyv12_to_uyvy_c(uint8_t * dst, int dst_stride, uint8_t * y_src, uint8_t * u_src, uint8_t * v_src, int y_stride, int uv_stride, int width, int height){ const uint32_t dst_dif = 2 * (dst_stride - width); uint32_t x, y; if (height < 0) { height = -height; y_src += (height - 1) * y_stride; u_src += (height / 2 - 1) * uv_stride; v_src += (height / 2 - 1) * uv_stride; y_stride = -y_stride; uv_stride = -uv_stride; } for (y = 0; y < (uint32_t) height; y++) { for (x = 0; x < (uint32_t) width / 2; x++) { dst[0] = u_src[x]; dst[1] = y_src[2 * x]; dst[2] = v_src[x]; dst[3] = y_src[2 * x + 1]; dst += 4; } dst += dst_dif; y_src += y_stride; if (y & 1) { u_src += uv_stride; v_src += uv_stride; } }}/* user yuv planar -> yuv 4:2:0 planar NOTE: does not flip */voiduser_to_yuv_c(uint8_t * y_out, uint8_t * u_out, uint8_t * v_out, int stride, DEC_PICTURE * picture, int width, int height){ uint32_t stride2 = stride >> 1; uint32_t width2 = width >> 1; uint32_t y; uint8_t *src; src = picture->y; for (y = height; y; y--) { memcpy(y_out, src, width); src += picture->stride_y; y_out += stride; } src = picture->u; for (y = height >> 1; y; y--) { memcpy(u_out, src, width2); src += picture->stride_uv; u_out += stride2; } src = picture->v; for (y = height >> 1; y; y--) { memcpy(v_out, src, width2); src += picture->stride_uv; v_out += stride2; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -