xref: /OK3568_Linux_fs/buildroot/package/pixman/0003-Support-PIXMAN_i420-format.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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