1From c61de7e05eaf00fa7514cbd0f5df6eecdebb15a4 Mon Sep 17 00:00:00 2001 2From: Jeffy Chen <jeffy.chen@rock-chips.com> 3Date: Mon, 4 Nov 2019 11:11:59 +0800 4Subject: [PATCH 3/6] Support PIXMAN_i420 format 5 6Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 7--- 8 pixman/pixman-access.c | 77 ++++++++++++++++++++++++++++++++++++++++++ 9 pixman/pixman.c | 4 ++- 10 pixman/pixman.h | 2 ++ 11 3 files changed, 82 insertions(+), 1 deletion(-) 12 13diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c 14index 1e5c0ba..e7f97ea 100644 15--- a/pixman/pixman-access.c 16+++ b/pixman/pixman-access.c 17@@ -192,6 +192,15 @@ 18 ((uint8_t *) ((bits) + offset0 + \ 19 ((stride) >> 1) * ((line) >> 1))) 20 21+/* 22+ * I420 setup and access macros 23+ */ 24+ 25+#define I420_SETUP(image) YV12_SETUP(image) 26+#define I420_Y(line) YV12_Y(line) 27+#define I420_U(line) YV12_V(line) 28+#define I420_V(line) YV12_U(line) 29+ 30 /* 31 * NV12 setup and access macros 32 */ 33@@ -864,6 +873,43 @@ fetch_scanline_yv12 (bits_image_t *image, 34 } 35 } 36 37+static void 38+fetch_scanline_i420 (bits_image_t *image, 39+ int x, 40+ int line, 41+ int width, 42+ uint32_t * buffer, 43+ const uint32_t *mask) 44+{ 45+ I420_SETUP (image); 46+ uint8_t *y_line = I420_Y (line); 47+ uint8_t *u_line = I420_U (line); 48+ uint8_t *v_line = I420_V (line); 49+ int i; 50+ 51+ for (i = 0; i < width; i++) 52+ { 53+ int16_t y, u, v; 54+ int32_t r, g, b; 55+ 56+ y = y_line[x + i] - 16; 57+ u = u_line[(x + i) >> 1] - 128; 58+ v = v_line[(x + i) >> 1] - 128; 59+ 60+ /* R = 1.164(Y - 16) + 1.596(V - 128) */ 61+ r = 0x012b27 * y + 0x019a2e * v; 62+ /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */ 63+ g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u; 64+ /* B = 1.164(Y - 16) + 2.018(U - 128) */ 65+ b = 0x012b27 * y + 0x0206a2 * u; 66+ 67+ *buffer++ = 0xff000000 | 68+ (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) | 69+ (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) | 70+ (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0); 71+ } 72+} 73+ 74 static void 75 fetch_scanline_nv12 (bits_image_t *image, 76 int x, 77@@ -1091,6 +1137,32 @@ fetch_pixel_yv12 (bits_image_t *image, 78 (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0); 79 } 80 81+static uint32_t 82+fetch_pixel_i420 (bits_image_t *image, 83+ int offset, 84+ int line) 85+{ 86+ I420_SETUP (image); 87+ int16_t y = I420_Y (line)[offset] - 16; 88+ int16_t u = I420_U (line)[offset >> 1] - 128; 89+ int16_t v = I420_V (line)[offset >> 1] - 128; 90+ int32_t r, g, b; 91+ 92+ /* R = 1.164(Y - 16) + 1.596(V - 128) */ 93+ r = 0x012b27 * y + 0x019a2e * v; 94+ 95+ /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */ 96+ g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u; 97+ 98+ /* B = 1.164(Y - 16) + 2.018(U - 128) */ 99+ b = 0x012b27 * y + 0x0206a2 * u; 100+ 101+ return 0xff000000 | 102+ (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) | 103+ (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) | 104+ (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0); 105+} 106+ 107 static uint32_t 108 fetch_pixel_nv12 (bits_image_t *image, 109 int offset, 110@@ -1589,6 +1661,11 @@ static const format_info_t accessors[] = 111 fetch_scanline_yv12, fetch_scanline_generic_float, 112 fetch_pixel_yv12, fetch_pixel_generic_float, 113 NULL, NULL }, 114+ 115+ { PIXMAN_i420, 116+ fetch_scanline_i420, fetch_scanline_generic_float, 117+ fetch_pixel_i420, fetch_pixel_generic_float, 118+ NULL, NULL }, 119 120 { PIXMAN_nv12, 121 fetch_scanline_nv12, fetch_scanline_generic_float, 122diff --git a/pixman/pixman.c b/pixman/pixman.c 123index d8a2d24..ac06002 100644 124--- a/pixman/pixman.c 125+++ b/pixman/pixman.c 126@@ -1070,6 +1070,7 @@ pixman_format_supported_source (pixman_format_code_t format) 127 /* YUV formats */ 128 case PIXMAN_yuy2: 129 case PIXMAN_yv12: 130+ case PIXMAN_i420: 131 case PIXMAN_nv12: 132 return TRUE; 133 134@@ -1093,7 +1094,8 @@ PIXMAN_EXPORT pixman_bool_t 135 pixman_format_supported_destination (pixman_format_code_t format) 136 { 137 /* YUV formats cannot be written to at the moment */ 138- if (format == PIXMAN_yuy2 || format == PIXMAN_yv12 || format == PIXMAN_nv12) 139+ if (format == PIXMAN_yuy2 || format == PIXMAN_yv12 || 140+ format == PIXMAN_nv12 || format == PIXMAN_i420) 141 return FALSE; 142 143 return pixman_format_supported_source (format); 144diff --git a/pixman/pixman.h b/pixman/pixman.h 145index 3bb2fa5..e8b0a78 100644 146--- a/pixman/pixman.h 147+++ b/pixman/pixman.h 148@@ -863,6 +863,7 @@ struct pixman_indexed 149 150 /* HACK: Use maximum value to avoid conflict */ 151 #define PIXMAN_TYPE_NV12 0x3f 152+#define PIXMAN_TYPE_I420 0x3e 153 154 #define PIXMAN_FORMAT_COLOR(f) \ 155 (PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ARGB || \ 156@@ -945,6 +946,7 @@ typedef enum { 157 /* YUV formats */ 158 PIXMAN_yuy2 = PIXMAN_FORMAT(16,PIXMAN_TYPE_YUY2,0,0,0,0), 159 PIXMAN_yv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0), 160+ PIXMAN_i420 = PIXMAN_FORMAT(12,PIXMAN_TYPE_I420,0,0,0,0), 161 PIXMAN_nv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_NV12,0,0,0,0), 162 } pixman_format_code_t; 163 164-- 1652.20.1 166 167