52 |
color_outputFuncPtr yv12_to_rgb565; |
color_outputFuncPtr yv12_to_rgb565; |
53 |
color_outputFuncPtr yv12_to_rgb24; |
color_outputFuncPtr yv12_to_rgb24; |
54 |
color_outputFuncPtr yv12_to_rgb32; |
color_outputFuncPtr yv12_to_rgb32; |
55 |
|
color_outputFuncPtr yv12_to_abgr; |
56 |
|
color_outputFuncPtr yv12_to_rgba; |
57 |
color_outputFuncPtr yv12_to_yuv; |
color_outputFuncPtr yv12_to_yuv; |
58 |
color_outputFuncPtr yv12_to_yuyv; |
color_outputFuncPtr yv12_to_yuyv; |
59 |
color_outputFuncPtr yv12_to_uyvy; |
color_outputFuncPtr yv12_to_uyvy; |
606 |
int width, |
int width, |
607 |
int height) |
int height) |
608 |
{ |
{ |
609 |
const uint32_t dst_dif = 4 * dst_stride - 2 * width; |
const uint32_t dst_dif = 2 * dst_stride - 2 * width; |
610 |
int32_t y_dif = 2 * y_stride - width; |
int32_t y_dif = 2 * y_stride - width; |
611 |
|
|
612 |
uint8_t *dst2 = dst + 2 * dst_stride; |
uint8_t *dst2 = dst + dst_stride; |
613 |
uint8_t *y_src2 = y_src + y_stride; |
uint8_t *y_src2 = y_src + y_stride; |
614 |
uint32_t x, y; |
uint32_t x, y; |
615 |
|
|
705 |
int width, |
int width, |
706 |
int height) |
int height) |
707 |
{ |
{ |
708 |
const uint32_t dst_dif = 4 * dst_stride - 2 * width; |
const uint32_t dst_dif = 2 * dst_stride - 2 * width; |
709 |
int32_t y_dif = 2 * y_stride - width; |
int32_t y_dif = 2 * y_stride - width; |
710 |
|
|
711 |
uint8_t *dst2 = dst + 2 * dst_stride; |
uint8_t *dst2 = dst + dst_stride; |
712 |
uint8_t *y_src2 = y_src + y_stride; |
uint8_t *y_src2 = y_src + y_stride; |
713 |
uint32_t x, y; |
uint32_t x, y; |
714 |
|
|
785 |
} |
} |
786 |
|
|
787 |
|
|
788 |
|
#define MAKE_YV12_TO_RGB_C(NAME,SIZE,C1,C2,C3,C4) \ |
789 |
/* yuv 4:2:0 planar -> rgb24 */ |
void yv12_to_##NAME##_c(uint8_t * dst, \ |
790 |
|
int dst_stride, \ |
791 |
void |
uint8_t * y_src, \ |
792 |
yv12_to_rgb24_c(uint8_t * dst, |
uint8_t * u_src, \ |
793 |
int dst_stride, |
uint8_t * v_src, \ |
794 |
uint8_t * y_src, |
int y_stride, \ |
795 |
uint8_t * u_src, |
int uv_stride, \ |
796 |
uint8_t * v_src, |
int width, \ |
797 |
int y_stride, |
int height) \ |
798 |
int uv_stride, |
{ \ |
799 |
int width, |
const uint8_t a = 0; /* alpha = 0 */ \ |
800 |
int height) |
const uint32_t dst_dif = 2 * dst_stride - (SIZE) * width; \ |
801 |
{ |
int32_t y_dif = 2 * y_stride - width; \ |
802 |
const uint32_t dst_dif = 6 * dst_stride - 3 * width; |
uint8_t *dst2 = dst + dst_stride; \ |
803 |
int32_t y_dif = 2 * y_stride - width; |
uint8_t *y_src2 = y_src + y_stride; \ |
804 |
|
uint32_t x, y; \ |
805 |
uint8_t *dst2 = dst + 3 * dst_stride; |
\ |
806 |
uint8_t *y_src2 = y_src + y_stride; |
if (height < 0) { /* flip image? */ \ |
807 |
uint32_t x, y; |
height = -height; \ |
808 |
|
y_src += (height - 1) * y_stride; \ |
809 |
if (height < 0) { // flip image? |
y_src2 = y_src - y_stride; \ |
810 |
height = -height; |
u_src += (height / 2 - 1) * uv_stride; \ |
811 |
y_src += (height - 1) * y_stride; |
v_src += (height / 2 - 1) * uv_stride; \ |
812 |
y_src2 = y_src - y_stride; |
y_dif = -width - 2 * y_stride; \ |
813 |
u_src += (height / 2 - 1) * uv_stride; |
uv_stride = -uv_stride; \ |
814 |
v_src += (height / 2 - 1) * uv_stride; |
} \ |
815 |
y_dif = -width - 2 * y_stride; |
/* process one 2x2 block per iteration */ \ |
816 |
uv_stride = -uv_stride; |
for (y = height/2; y; y--) { \ |
817 |
} |
\ |
818 |
|
for (x = 0; x < (uint32_t)width/2; x++) { \ |
819 |
for (y = height / 2; y; y--) { |
int u, v; \ |
820 |
// process one 2x2 block per iteration |
int b_u, g_uv, r_v, rgb_y; \ |
821 |
for (x = 0; x < (uint32_t) width / 2; x++) { |
int r, g, b; \ |
822 |
int u, v; |
\ |
823 |
int b_u, g_uv, r_v, rgb_y; |
u = u_src[x]; \ |
824 |
int r, g, b; |
v = v_src[x]; \ |
825 |
|
b_u = B_U_tab[u]; \ |
826 |
u = u_src[x]; |
g_uv = G_U_tab[u] + G_V_tab[v]; \ |
827 |
v = v_src[x]; |
r_v = R_V_tab[v]; \ |
828 |
|
\ |
829 |
b_u = B_U_tab[u]; |
rgb_y = RGB_Y_tab[*y_src]; \ |
830 |
g_uv = G_U_tab[u] + G_V_tab[v]; |
b = MAX(0, MIN(255, (rgb_y + b_u) >> SCALEBITS_OUT)); \ |
831 |
r_v = R_V_tab[v]; |
g = MAX(0, MIN(255, (rgb_y - g_uv) >> SCALEBITS_OUT)); \ |
832 |
|
r = MAX(0, MIN(255, (rgb_y + r_v) >> SCALEBITS_OUT)); \ |
833 |
rgb_y = RGB_Y_tab[*y_src]; |
dst[0] = (C1); \ |
834 |
b = (rgb_y + b_u) >> SCALEBITS_OUT; |
dst[1] = (C2); \ |
835 |
g = (rgb_y - g_uv) >> SCALEBITS_OUT; |
dst[2] = (C3); \ |
836 |
r = (rgb_y + r_v) >> SCALEBITS_OUT; |
if ((SIZE)>3) dst[3] = (C4); \ |
837 |
dst[0] = MAX(0, MIN(255, b)); |
y_src++; \ |
838 |
dst[1] = MAX(0, MIN(255, g)); |
\ |
839 |
dst[2] = MAX(0, MIN(255, r)); |
rgb_y = RGB_Y_tab[*y_src]; \ |
840 |
|
b = MAX(0, MIN(255, (rgb_y + b_u) >> SCALEBITS_OUT)); \ |
841 |
y_src++; |
g = MAX(0, MIN(255, (rgb_y - g_uv) >> SCALEBITS_OUT)); \ |
842 |
rgb_y = RGB_Y_tab[*y_src]; |
r = MAX(0, MIN(255, (rgb_y + r_v) >> SCALEBITS_OUT)); \ |
843 |
b = (rgb_y + b_u) >> SCALEBITS_OUT; |
dst[(SIZE)+0] = (C1); \ |
844 |
g = (rgb_y - g_uv) >> SCALEBITS_OUT; |
dst[(SIZE)+1] = (C2); \ |
845 |
r = (rgb_y + r_v) >> SCALEBITS_OUT; |
dst[(SIZE)+2] = (C3); \ |
846 |
dst[3] = MAX(0, MIN(255, b)); |
if ((SIZE)>3) dst[(SIZE)+3] = (C4); \ |
847 |
dst[4] = MAX(0, MIN(255, g)); |
y_src++; \ |
848 |
dst[5] = MAX(0, MIN(255, r)); |
\ |
849 |
y_src++; |
rgb_y = RGB_Y_tab[*y_src2]; \ |
850 |
|
b = MAX(0, MIN(255, (rgb_y + b_u) >> SCALEBITS_OUT)); \ |
851 |
rgb_y = RGB_Y_tab[*y_src2]; |
g = MAX(0, MIN(255, (rgb_y - g_uv) >> SCALEBITS_OUT)); \ |
852 |
b = (rgb_y + b_u) >> SCALEBITS_OUT; |
r = MAX(0, MIN(255, (rgb_y + r_v) >> SCALEBITS_OUT)); \ |
853 |
g = (rgb_y - g_uv) >> SCALEBITS_OUT; |
dst2[0] = (C1); \ |
854 |
r = (rgb_y + r_v) >> SCALEBITS_OUT; |
dst2[1] = (C2); \ |
855 |
dst2[0] = MAX(0, MIN(255, b)); |
dst2[2] = (C3); \ |
856 |
dst2[1] = MAX(0, MIN(255, g)); |
if ((SIZE)>3) dst2[3] = (C4); \ |
857 |
dst2[2] = MAX(0, MIN(255, r)); |
y_src2++; \ |
858 |
y_src2++; |
\ |
859 |
|
rgb_y = RGB_Y_tab[*y_src2]; \ |
860 |
rgb_y = RGB_Y_tab[*y_src2]; |
b = MAX(0, MIN(255, (rgb_y + b_u) >> SCALEBITS_OUT)); \ |
861 |
b = (rgb_y + b_u) >> SCALEBITS_OUT; |
g = MAX(0, MIN(255, (rgb_y - g_uv) >> SCALEBITS_OUT)); \ |
862 |
g = (rgb_y - g_uv) >> SCALEBITS_OUT; |
r = MAX(0, MIN(255, (rgb_y + r_v) >> SCALEBITS_OUT)); \ |
863 |
r = (rgb_y + r_v) >> SCALEBITS_OUT; |
dst2[(SIZE)+0] = (C1); \ |
864 |
dst2[3] = MAX(0, MIN(255, b)); |
dst2[(SIZE)+1] = (C2); \ |
865 |
dst2[4] = MAX(0, MIN(255, g)); |
dst2[(SIZE)+2] = (C3); \ |
866 |
dst2[5] = MAX(0, MIN(255, r)); |
if ((SIZE)>3) dst2[(SIZE)+3] = (C4); \ |
867 |
y_src2++; |
y_src2++; \ |
868 |
|
\ |
869 |
dst += 6; |
dst += 2*(SIZE); \ |
870 |
dst2 += 6; |
dst2 += 2*(SIZE); \ |
871 |
} |
} \ |
872 |
|
dst += dst_dif; \ |
873 |
dst += dst_dif; |
dst2 += dst_dif; \ |
874 |
dst2 += dst_dif; |
y_src += y_dif; \ |
875 |
|
y_src2 += y_dif; \ |
876 |
y_src += y_dif; |
u_src += uv_stride; \ |
877 |
y_src2 += y_dif; |
v_src += uv_stride; \ |
878 |
|
} \ |
879 |
u_src += uv_stride; |
} |
880 |
v_src += uv_stride; |
|
881 |
} |
MAKE_YV12_TO_RGB_C(rgb24,3, b,g,r,0) /* yuv420 -> bgr */ |
882 |
} |
MAKE_YV12_TO_RGB_C(rgb32,4, b,g,r,a) /* yuv420 -> bgra */ |
883 |
|
MAKE_YV12_TO_RGB_C(abgr, 4, a,b,g,r) /* yuv420 -> abgr */ |
884 |
|
MAKE_YV12_TO_RGB_C(rgba, 4, r,g,b,a) /* yuv420 -> rgba */ |
|
|
|
|
/* yuv 4:2:0 planar -> rgb32 */ |
|
|
|
|
|
void |
|
|
yv12_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; |
|
|
} |
|
|
} |
|
885 |
|
|
886 |
|
|
887 |
|
|
946 |
int width, |
int width, |
947 |
int height) |
int height) |
948 |
{ |
{ |
949 |
const uint32_t dst_dif = 2 * (dst_stride - width); |
const uint32_t dst_dif = dst_stride - (2 * width); |
950 |
uint32_t x, y; |
uint32_t x, y; |
951 |
|
|
952 |
if (height < 0) { |
if (height < 0) { |
990 |
int width, |
int width, |
991 |
int height) |
int height) |
992 |
{ |
{ |
993 |
const uint32_t dst_dif = 2 * (dst_stride - width); |
const uint32_t dst_dif = dst_stride - (2 * width); |
994 |
uint32_t x, y; |
uint32_t x, y; |
995 |
|
|
996 |
if (height < 0) { |
if (height < 0) { |