HYL_OK3568_LINUX/buildroot/package/pixman/0003-Support-PIXMAN_i420-format.patch
2025-05-10 21:49:39 +08:00

167 lines
5.2 KiB
Diff

From c61de7e05eaf00fa7514cbd0f5df6eecdebb15a4 Mon Sep 17 00:00:00 2001
From: Jeffy Chen <jeffy.chen@rock-chips.com>
Date: Mon, 4 Nov 2019 11:11:59 +0800
Subject: [PATCH 3/6] Support PIXMAN_i420 format
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
---
pixman/pixman-access.c | 77 ++++++++++++++++++++++++++++++++++++++++++
pixman/pixman.c | 4 ++-
pixman/pixman.h | 2 ++
3 files changed, 82 insertions(+), 1 deletion(-)
diff --git a/pixman/pixman-access.c b/pixman/pixman-access.c
index 1e5c0ba..e7f97ea 100644
--- a/pixman/pixman-access.c
+++ b/pixman/pixman-access.c
@@ -192,6 +192,15 @@
((uint8_t *) ((bits) + offset0 + \
((stride) >> 1) * ((line) >> 1)))
+/*
+ * I420 setup and access macros
+ */
+
+#define I420_SETUP(image) YV12_SETUP(image)
+#define I420_Y(line) YV12_Y(line)
+#define I420_U(line) YV12_V(line)
+#define I420_V(line) YV12_U(line)
+
/*
* NV12 setup and access macros
*/
@@ -864,6 +873,43 @@ fetch_scanline_yv12 (bits_image_t *image,
}
}
+static void
+fetch_scanline_i420 (bits_image_t *image,
+ int x,
+ int line,
+ int width,
+ uint32_t * buffer,
+ const uint32_t *mask)
+{
+ I420_SETUP (image);
+ uint8_t *y_line = I420_Y (line);
+ uint8_t *u_line = I420_U (line);
+ uint8_t *v_line = I420_V (line);
+ int i;
+
+ for (i = 0; i < width; i++)
+ {
+ int16_t y, u, v;
+ int32_t r, g, b;
+
+ y = y_line[x + i] - 16;
+ u = u_line[(x + i) >> 1] - 128;
+ v = v_line[(x + i) >> 1] - 128;
+
+ /* R = 1.164(Y - 16) + 1.596(V - 128) */
+ r = 0x012b27 * y + 0x019a2e * v;
+ /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
+ g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
+ /* B = 1.164(Y - 16) + 2.018(U - 128) */
+ b = 0x012b27 * y + 0x0206a2 * u;
+
+ *buffer++ = 0xff000000 |
+ (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
+ (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
+ (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
+ }
+}
+
static void
fetch_scanline_nv12 (bits_image_t *image,
int x,
@@ -1091,6 +1137,32 @@ fetch_pixel_yv12 (bits_image_t *image,
(b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
}
+static uint32_t
+fetch_pixel_i420 (bits_image_t *image,
+ int offset,
+ int line)
+{
+ I420_SETUP (image);
+ int16_t y = I420_Y (line)[offset] - 16;
+ int16_t u = I420_U (line)[offset >> 1] - 128;
+ int16_t v = I420_V (line)[offset >> 1] - 128;
+ int32_t r, g, b;
+
+ /* R = 1.164(Y - 16) + 1.596(V - 128) */
+ r = 0x012b27 * y + 0x019a2e * v;
+
+ /* G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) */
+ g = 0x012b27 * y - 0x00d0f2 * v - 0x00647e * u;
+
+ /* B = 1.164(Y - 16) + 2.018(U - 128) */
+ b = 0x012b27 * y + 0x0206a2 * u;
+
+ return 0xff000000 |
+ (r >= 0 ? r < 0x1000000 ? r & 0xff0000 : 0xff0000 : 0) |
+ (g >= 0 ? g < 0x1000000 ? (g >> 8) & 0x00ff00 : 0x00ff00 : 0) |
+ (b >= 0 ? b < 0x1000000 ? (b >> 16) & 0x0000ff : 0x0000ff : 0);
+}
+
static uint32_t
fetch_pixel_nv12 (bits_image_t *image,
int offset,
@@ -1589,6 +1661,11 @@ static const format_info_t accessors[] =
fetch_scanline_yv12, fetch_scanline_generic_float,
fetch_pixel_yv12, fetch_pixel_generic_float,
NULL, NULL },
+
+ { PIXMAN_i420,
+ fetch_scanline_i420, fetch_scanline_generic_float,
+ fetch_pixel_i420, fetch_pixel_generic_float,
+ NULL, NULL },
{ PIXMAN_nv12,
fetch_scanline_nv12, fetch_scanline_generic_float,
diff --git a/pixman/pixman.c b/pixman/pixman.c
index d8a2d24..ac06002 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -1070,6 +1070,7 @@ pixman_format_supported_source (pixman_format_code_t format)
/* YUV formats */
case PIXMAN_yuy2:
case PIXMAN_yv12:
+ case PIXMAN_i420:
case PIXMAN_nv12:
return TRUE;
@@ -1093,7 +1094,8 @@ PIXMAN_EXPORT pixman_bool_t
pixman_format_supported_destination (pixman_format_code_t format)
{
/* YUV formats cannot be written to at the moment */
- if (format == PIXMAN_yuy2 || format == PIXMAN_yv12 || format == PIXMAN_nv12)
+ if (format == PIXMAN_yuy2 || format == PIXMAN_yv12 ||
+ format == PIXMAN_nv12 || format == PIXMAN_i420)
return FALSE;
return pixman_format_supported_source (format);
diff --git a/pixman/pixman.h b/pixman/pixman.h
index 3bb2fa5..e8b0a78 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -863,6 +863,7 @@ struct pixman_indexed
/* HACK: Use maximum value to avoid conflict */
#define PIXMAN_TYPE_NV12 0x3f
+#define PIXMAN_TYPE_I420 0x3e
#define PIXMAN_FORMAT_COLOR(f) \
(PIXMAN_FORMAT_TYPE(f) == PIXMAN_TYPE_ARGB || \
@@ -945,6 +946,7 @@ typedef enum {
/* YUV formats */
PIXMAN_yuy2 = PIXMAN_FORMAT(16,PIXMAN_TYPE_YUY2,0,0,0,0),
PIXMAN_yv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_YV12,0,0,0,0),
+ PIXMAN_i420 = PIXMAN_FORMAT(12,PIXMAN_TYPE_I420,0,0,0,0),
PIXMAN_nv12 = PIXMAN_FORMAT(12,PIXMAN_TYPE_NV12,0,0,0,0),
} pixman_format_code_t;
--
2.20.1