mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-08 01:36:47 +08:00
Add J420AlphaToARGB and colortests for bt.709 and rec.2020
Bug: libyuv:864, b/159753166 Change-Id: If6ba742a0e7c5baeab29e8b92569aee361af88e9 Reviewed-on: https://chromium-review.googlesource.com/c/libyuv/libyuv/+/2261568 Reviewed-by: Dale Curtis <dalecurtis@chromium.org> Commit-Queue: Frank Barchard <fbarchard@chromium.org>
This commit is contained in:
parent
c5e45dcae5
commit
0b793d9fac
@ -1,6 +1,6 @@
|
||||
Name: libyuv
|
||||
URL: http://code.google.com/p/libyuv/
|
||||
Version: 1759
|
||||
Version: 1760
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
|
||||
|
||||
@ -47,6 +47,8 @@ LIBYUV_API extern const struct YuvConstants kYvu2020Constants; // BT.2020
|
||||
NV21ToRGB24Matrix(a, b, c, d, e, f, g##VU, h, i)
|
||||
#define NV21ToRAWMatrix(a, b, c, d, e, f, g, h, i) \
|
||||
NV12ToRGB24Matrix(a, b, c, d, e, f, g##VU, h, i)
|
||||
#define I420AlphaToABGRMatrix(a, b, c, d, e, f, g, h, i, j, k, l, m, n) \
|
||||
I420AlphaToARGBMatrix(a, b, e, f, c, d, g, h, i, j, k##VU, l, m, n)
|
||||
|
||||
// Alias.
|
||||
#define ARGBToARGB ARGBCopy
|
||||
|
||||
@ -11,6 +11,6 @@
|
||||
#ifndef INCLUDE_LIBYUV_VERSION_H_
|
||||
#define INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
#define LIBYUV_VERSION 1759
|
||||
#define LIBYUV_VERSION 1760
|
||||
|
||||
#endif // INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
@ -1586,7 +1586,7 @@ const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = {
|
||||
|
||||
// BT.2020 YUV to RGB reference
|
||||
// R = (Y - 16) * 1.164384 - V * -1.67867
|
||||
// G = (Y - 16) * 1.164384 - U * 0.187326 - V * -0.65042
|
||||
// G = (Y - 16) * 1.164384 - U * 0.187326 - V * 0.65042
|
||||
// B = (Y - 16) * 1.164384 - U * -2.14177
|
||||
|
||||
// Y contribution to R,G,B. Scale and bias.
|
||||
@ -1594,6 +1594,7 @@ const struct YuvConstants SIMD_ALIGNED(kYvuH709Constants) = {
|
||||
#define YGB -1160 /* 1.164384 * 64 * -16 + 64 / 2 */
|
||||
|
||||
// TODO(fbarchard): Improve accuracy; the B channel is off by 7%.
|
||||
// U and V contributions to R,G,B.
|
||||
#define UB -128 /* max(-128, round(-2.142 * 64)) */
|
||||
#define UG 12 /* round(0.187326 * 64) */
|
||||
#define VG 42 /* round(0.65042 * 64) */
|
||||
|
||||
@ -187,6 +187,52 @@ static void YUVJToRGB(int y, int u, int v, int* r, int* g, int* b) {
|
||||
*r = orig_pixels[2];
|
||||
}
|
||||
|
||||
static void YUVHToRGB(int y, int u, int v, int* r, int* g, int* b) {
|
||||
const int kWidth = 16;
|
||||
const int kHeight = 1;
|
||||
const int kPixels = kWidth * kHeight;
|
||||
const int kHalfPixels = ((kWidth + 1) / 2) * ((kHeight + 1) / 2);
|
||||
|
||||
SIMD_ALIGNED(uint8_t orig_y[16]);
|
||||
SIMD_ALIGNED(uint8_t orig_u[8]);
|
||||
SIMD_ALIGNED(uint8_t orig_v[8]);
|
||||
SIMD_ALIGNED(uint8_t orig_pixels[16 * 4]);
|
||||
memset(orig_y, y, kPixels);
|
||||
memset(orig_u, u, kHalfPixels);
|
||||
memset(orig_v, v, kHalfPixels);
|
||||
|
||||
/* YUV converted to ARGB. */
|
||||
H422ToARGB(orig_y, kWidth, orig_u, (kWidth + 1) / 2, orig_v, (kWidth + 1) / 2,
|
||||
orig_pixels, kWidth * 4, kWidth, kHeight);
|
||||
|
||||
*b = orig_pixels[0];
|
||||
*g = orig_pixels[1];
|
||||
*r = orig_pixels[2];
|
||||
}
|
||||
|
||||
static void YUVRec2020ToRGB(int y, int u, int v, int* r, int* g, int* b) {
|
||||
const int kWidth = 16;
|
||||
const int kHeight = 1;
|
||||
const int kPixels = kWidth * kHeight;
|
||||
const int kHalfPixels = ((kWidth + 1) / 2) * ((kHeight + 1) / 2);
|
||||
|
||||
SIMD_ALIGNED(uint8_t orig_y[16]);
|
||||
SIMD_ALIGNED(uint8_t orig_u[8]);
|
||||
SIMD_ALIGNED(uint8_t orig_v[8]);
|
||||
SIMD_ALIGNED(uint8_t orig_pixels[16 * 4]);
|
||||
memset(orig_y, y, kPixels);
|
||||
memset(orig_u, u, kHalfPixels);
|
||||
memset(orig_v, v, kHalfPixels);
|
||||
|
||||
/* YUV converted to ARGB. */
|
||||
U422ToARGB(orig_y, kWidth, orig_u, (kWidth + 1) / 2, orig_v, (kWidth + 1) / 2,
|
||||
orig_pixels, kWidth * 4, kWidth, kHeight);
|
||||
|
||||
*b = orig_pixels[0];
|
||||
*g = orig_pixels[1];
|
||||
*r = orig_pixels[2];
|
||||
}
|
||||
|
||||
static void YToRGB(int y, int* r, int* g, int* b) {
|
||||
const int kWidth = 16;
|
||||
const int kHeight = 1;
|
||||
@ -335,18 +381,37 @@ TEST_F(LibYUVColorTest, TestRoundToByte) {
|
||||
EXPECT_LE(allb, 255);
|
||||
}
|
||||
|
||||
// BT.601 YUV to RGB reference
|
||||
static void YUVToRGBReference(int y, int u, int v, int* r, int* g, int* b) {
|
||||
*r = RoundToByte((y - 16) * 1.164 - (v - 128) * -1.596);
|
||||
*g = RoundToByte((y - 16) * 1.164 - (u - 128) * 0.391 - (v - 128) * 0.813);
|
||||
*b = RoundToByte((y - 16) * 1.164 - (u - 128) * -2.018);
|
||||
}
|
||||
|
||||
// JPEG YUV to RGB reference
|
||||
static void YUVJToRGBReference(int y, int u, int v, int* r, int* g, int* b) {
|
||||
*r = RoundToByte(y - (v - 128) * -1.40200);
|
||||
*g = RoundToByte(y - (u - 128) * 0.34414 - (v - 128) * 0.71414);
|
||||
*b = RoundToByte(y - (u - 128) * -1.77200);
|
||||
}
|
||||
|
||||
// BT.709 YUV to RGB reference
|
||||
// See also http://www.equasys.de/colorconversion.html
|
||||
static void YUVHToRGBReference(int y, int u, int v, int* r, int* g, int* b) {
|
||||
*r = RoundToByte((y - 16) * 1.164 - (v - 128) * -1.793);
|
||||
*g = RoundToByte((y - 16) * 1.164 - (u - 128) * 0.213 - (v - 128) * 0.533);
|
||||
*b = RoundToByte((y - 16) * 1.164 - (u - 128) * -2.112);
|
||||
}
|
||||
|
||||
// BT.2020 YUV to RGB reference
|
||||
static void YUVRec2020ToRGBReference(int y, int u, int v, int* r, int* g,
|
||||
int* b) {
|
||||
*r = RoundToByte((y - 16) * 1.164384 - (v - 128) * -1.67867);
|
||||
*g = RoundToByte((y - 16) * 1.164384 - (u - 128) * 0.187326 -
|
||||
(v - 128) * 0.65042);
|
||||
*b = RoundToByte((y - 16) * 1.164384 - (u - 128) * -2.14177);
|
||||
}
|
||||
|
||||
TEST_F(LibYUVColorTest, TestYUV) {
|
||||
int r0, g0, b0, r1, g1, b1;
|
||||
|
||||
@ -473,7 +538,11 @@ static void PrintHistogram(int rh[256], int gh[256], int bh[256]) {
|
||||
|
||||
// Step by 5 on inner loop goes from 0 to 255 inclusive.
|
||||
// Set to 1 for better converage. 3, 5 or 17 for faster testing.
|
||||
#ifdef ENABLE_SLOW_TESTS
|
||||
#define FASTSTEP 1
|
||||
#else
|
||||
#define FASTSTEP 5
|
||||
#endif
|
||||
TEST_F(LibYUVColorTest, TestFullYUV) {
|
||||
int rh[256] = {
|
||||
0,
|
||||
@ -531,6 +600,66 @@ TEST_F(LibYUVColorTest, TestFullYUVJ) {
|
||||
}
|
||||
PrintHistogram(rh, gh, bh);
|
||||
}
|
||||
|
||||
TEST_F(LibYUVColorTest, TestFullYUVH) {
|
||||
int rh[256] = {
|
||||
0,
|
||||
};
|
||||
int gh[256] = {
|
||||
0,
|
||||
};
|
||||
int bh[256] = {
|
||||
0,
|
||||
};
|
||||
for (int u = 0; u < 256; ++u) {
|
||||
for (int v = 0; v < 256; ++v) {
|
||||
for (int y2 = 0; y2 < 256; y2 += FASTSTEP) {
|
||||
int r0, g0, b0, r1, g1, b1;
|
||||
int y = RANDOM256(y2);
|
||||
YUVHToRGBReference(y, u, v, &r0, &g0, &b0);
|
||||
YUVHToRGB(y, u, v, &r1, &g1, &b1);
|
||||
EXPECT_NEAR(r0, r1, ERROR_R);
|
||||
EXPECT_NEAR(g0, g1, ERROR_G);
|
||||
// TODO(crbug.com/libyuv/862): Reduce the errors in the B channel.
|
||||
EXPECT_NEAR(b0, b1, 15);
|
||||
++rh[r1 - r0 + 128];
|
||||
++gh[g1 - g0 + 128];
|
||||
++bh[b1 - b0 + 128];
|
||||
}
|
||||
}
|
||||
}
|
||||
PrintHistogram(rh, gh, bh);
|
||||
}
|
||||
|
||||
TEST_F(LibYUVColorTest, TestFullYUVRec2020) {
|
||||
int rh[256] = {
|
||||
0,
|
||||
};
|
||||
int gh[256] = {
|
||||
0,
|
||||
};
|
||||
int bh[256] = {
|
||||
0,
|
||||
};
|
||||
for (int u = 0; u < 256; ++u) {
|
||||
for (int v = 0; v < 256; ++v) {
|
||||
for (int y2 = 0; y2 < 256; y2 += FASTSTEP) {
|
||||
int r0, g0, b0, r1, g1, b1;
|
||||
int y = RANDOM256(y2);
|
||||
YUVRec2020ToRGBReference(y, u, v, &r0, &g0, &b0);
|
||||
YUVRec2020ToRGB(y, u, v, &r1, &g1, &b1);
|
||||
EXPECT_NEAR(r0, r1, ERROR_R);
|
||||
EXPECT_NEAR(g0, g1, ERROR_G);
|
||||
// TODO(crbug.com/libyuv/863): Reduce the errors in the B channel.
|
||||
EXPECT_NEAR(b0, b1, 18);
|
||||
++rh[r1 - r0 + 128];
|
||||
++gh[g1 - g0 + 128];
|
||||
++bh[b1 - b0 + 128];
|
||||
}
|
||||
}
|
||||
}
|
||||
PrintHistogram(rh, gh, bh);
|
||||
}
|
||||
#undef FASTSTEP
|
||||
|
||||
TEST_F(LibYUVColorTest, TestGreyYUVJ) {
|
||||
|
||||
@ -2532,8 +2532,27 @@ TESTPLANARTOE(I422, 2, 1, UYVY, 2, 4, ARGB, 4)
|
||||
TESTQPLANARTOEI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, SUB_B, BPP_B, \
|
||||
benchmark_width_, _Premult, +, 0, FMT_C, BPP_C, 1)
|
||||
|
||||
#define J420AlphaToARGB(a, b, c, d, e, f, g, h, i, j, k, l, m) \
|
||||
I420AlphaToARGBMatrix(a, b, c, d, e, f, g, h, i, j, &kYuvJPEGConstants, k, l, m)
|
||||
#define J420AlphaToABGR(a, b, c, d, e, f, g, h, i, j, k, l, m) \
|
||||
I420AlphaToABGRMatrix(a, b, c, d, e, f, g, h, i, j, &kYuvJPEGConstants, k, l, m)
|
||||
#define H420AlphaToARGB(a, b, c, d, e, f, g, h, i, j, k, l, m) \
|
||||
I420AlphaToARGBMatrix(a, b, c, d, e, f, g, h, i, j, &kYuvH709Constants, k, l, m)
|
||||
#define H420AlphaToABGR(a, b, c, d, e, f, g, h, i, j, k, l, m) \
|
||||
I420AlphaToABGRMatrix(a, b, c, d, e, f, g, h, i, j, &kYuvH709Constants, k, l, m)
|
||||
#define U420AlphaToARGB(a, b, c, d, e, f, g, h, i, j, k, l, m) \
|
||||
I420AlphaToARGBMatrix(a, b, c, d, e, f, g, h, i, j, &kYuv2020Constants, k, l, m)
|
||||
#define U420AlphaToABGR(a, b, c, d, e, f, g, h, i, j, k, l, m) \
|
||||
I420AlphaToABGRMatrix(a, b, c, d, e, f, g, h, i, j, &kYuv2020Constants, k, l, m)
|
||||
|
||||
TESTQPLANARTOE(I420Alpha, 2, 2, ARGB, 1, 4, ABGR, 4)
|
||||
TESTQPLANARTOE(I420Alpha, 2, 2, ABGR, 1, 4, ARGB, 4)
|
||||
TESTQPLANARTOE(J420Alpha, 2, 2, ARGB, 1, 4, ABGR, 4)
|
||||
TESTQPLANARTOE(J420Alpha, 2, 2, ABGR, 1, 4, ARGB, 4)
|
||||
TESTQPLANARTOE(H420Alpha, 2, 2, ARGB, 1, 4, ABGR, 4)
|
||||
TESTQPLANARTOE(H420Alpha, 2, 2, ABGR, 1, 4, ARGB, 4)
|
||||
TESTQPLANARTOE(U420Alpha, 2, 2, ARGB, 1, 4, ABGR, 4)
|
||||
TESTQPLANARTOE(U420Alpha, 2, 2, ABGR, 1, 4, ARGB, 4)
|
||||
|
||||
#define TESTPLANETOEI(FMT_A, SUB_A, BPP_A, FMT_B, SUB_B, BPP_B, W1280, N, NEG, \
|
||||
OFF, FMT_C, BPP_C) \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user