mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2026-02-06 09:49:50 +08:00
change Y multiplier and bias to compensate for 257/256 which makes YToARGB exactly match float math.
Histogram Before hist -3 -2 -1 0 1 2 3 red 0 0 1809408 13140736 1827072 0 0 green 0 0 1679912 13471329 1625975 0 0 blue 168448 994816 1876480 10655488 1893376 1006336 182272 Histogram After hist -3 -2 -1 0 1 2 3 red 0 0 558848 15632128 586240 0 0 green 0 0 209907 16350588 216721 0 0 blue 14848 642816 1989376 11363328 2053120 695040 18688 BUG=394 TESTED=more stringent luma tests R=brucedawson@google.com Review URL: https://webrtc-codereview.appspot.com/38859004 git-svn-id: http://libyuv.googlecode.com/svn/trunk@1259 16f28f9a-4ce2-e073-06de-1de4eb20be90
This commit is contained in:
parent
3982998c7c
commit
c4e032c543
@ -1,6 +1,6 @@
|
|||||||
Name: libyuv
|
Name: libyuv
|
||||||
URL: http://code.google.com/p/libyuv/
|
URL: http://code.google.com/p/libyuv/
|
||||||
Version: 1258
|
Version: 1259
|
||||||
License: BSD
|
License: BSD
|
||||||
License File: LICENSE
|
License File: LICENSE
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,6 @@
|
|||||||
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
|
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
|
||||||
#define INCLUDE_LIBYUV_VERSION_H_
|
#define INCLUDE_LIBYUV_VERSION_H_
|
||||||
|
|
||||||
#define LIBYUV_VERSION 1258
|
#define LIBYUV_VERSION 1259
|
||||||
|
|
||||||
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
|
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
|
||||||
|
|||||||
@ -962,8 +962,9 @@ void I400ToARGBRow_C(const uint8* src_y, uint8* dst_argb, int width) {
|
|||||||
|
|
||||||
// YUV to RGB conversion constants.
|
// YUV to RGB conversion constants.
|
||||||
// Y contribution to R,G,B. Scale and bias.
|
// Y contribution to R,G,B. Scale and bias.
|
||||||
#define YG 19071 /* round(1.164 * 64 * 256) */
|
// TODO(fbarchard): Consider moving constants into a common header.
|
||||||
#define YGB 1197 /* 1.164 * 64 * 16 - adjusted for even error distribution */
|
#define YG 18997 /* round(1.164 * 64 * 256 * 256 / 257) */
|
||||||
|
#define YGB 1160 /* 1.164 * 64 * 16 - adjusted for even error distribution */
|
||||||
|
|
||||||
// U and V contributions to R,G,B.
|
// U and V contributions to R,G,B.
|
||||||
#define UB -128 /* -min(128, round(2.018 * 64)) */
|
#define UB -128 /* -min(128, round(2.018 * 64)) */
|
||||||
|
|||||||
@ -1522,8 +1522,8 @@ void RGBAToUVRow_SSSE3(const uint8* src_rgba0, int src_stride_rgba,
|
|||||||
|
|
||||||
// YUV to RGB conversion constants.
|
// YUV to RGB conversion constants.
|
||||||
// Y contribution to R,G,B. Scale and bias.
|
// Y contribution to R,G,B. Scale and bias.
|
||||||
#define YG 19071 /* round(1.164 * 64 * 256) */
|
#define YG 18997 /* round(1.164 * 64 * 256 * 256 / 257) */
|
||||||
#define YGB 1197 /* 1.164 * 64 * 16 - adjusted for even error distribution */
|
#define YGB 1160 /* 1.164 * 64 * 16 - adjusted for even error distribution */
|
||||||
|
|
||||||
// U and V contributions to R,G,B.
|
// U and V contributions to R,G,B.
|
||||||
#define UB -128 /* -min(128, round(2.018 * 64)) */
|
#define UB -128 /* -min(128, round(2.018 * 64)) */
|
||||||
@ -2296,14 +2296,14 @@ void YToARGBRow_SSE2(const uint8* y_buf,
|
|||||||
uint8* dst_argb,
|
uint8* dst_argb,
|
||||||
int width) {
|
int width) {
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"pcmpeqb %%xmm4,%%xmm4 \n"
|
"mov $0x4a354a35,%%eax \n" // 4a35 = 18997 = 1.164
|
||||||
"pslld $0x18,%%xmm4 \n"
|
|
||||||
"mov $0x04ad04ad,%%eax \n" // 04ad = 1197 = 1.164 * 16
|
|
||||||
"movd %%eax,%%xmm3 \n"
|
|
||||||
"pshufd $0x0,%%xmm3,%%xmm3 \n"
|
|
||||||
"mov $0x4a7f4a7f,%%eax \n" // 4a7f = 19071 = 1.164
|
|
||||||
"movd %%eax,%%xmm2 \n"
|
"movd %%eax,%%xmm2 \n"
|
||||||
"pshufd $0x0,%%xmm2,%%xmm2 \n"
|
"pshufd $0x0,%%xmm2,%%xmm2 \n"
|
||||||
|
"mov $0x04880488,%%eax \n" // 0488 = 1160 = 1.164 * 16
|
||||||
|
"movd %%eax,%%xmm3 \n"
|
||||||
|
"pshufd $0x0,%%xmm3,%%xmm3 \n"
|
||||||
|
"pcmpeqb %%xmm4,%%xmm4 \n"
|
||||||
|
"pslld $0x18,%%xmm4 \n"
|
||||||
LABELALIGN
|
LABELALIGN
|
||||||
"1: \n"
|
"1: \n"
|
||||||
// Step 1: Scale Y contribution to 8 G values. G = (y - 16) * 1.164
|
// Step 1: Scale Y contribution to 8 G values. G = (y - 16) * 1.164
|
||||||
|
|||||||
@ -26,8 +26,8 @@ extern "C" {
|
|||||||
|
|
||||||
// YUV to RGB conversion constants.
|
// YUV to RGB conversion constants.
|
||||||
// Y contribution to R,G,B. Scale and bias.
|
// Y contribution to R,G,B. Scale and bias.
|
||||||
#define YG 19071 /* round(1.164 * 64 * 256) */
|
#define YG 18997 /* round(1.164 * 64 * 256 * 256 / 257) */
|
||||||
#define YGB 1197 /* 1.164 * 64 * 16 - adjusted for even error distribution */
|
#define YGB 1160 /* 1.164 * 64 * 16 - adjusted for even error distribution */
|
||||||
|
|
||||||
// U and V contributions to R,G,B.
|
// U and V contributions to R,G,B.
|
||||||
#define UB -128 /* -min(128, round(2.018 * 64)) */
|
#define UB -128 /* -min(128, round(2.018 * 64)) */
|
||||||
@ -2306,14 +2306,14 @@ void YToARGBRow_SSE2(const uint8* y_buf,
|
|||||||
uint8* rgb_buf,
|
uint8* rgb_buf,
|
||||||
int width) {
|
int width) {
|
||||||
__asm {
|
__asm {
|
||||||
pcmpeqb xmm4, xmm4 // generate mask 0xff000000
|
mov eax, 0x4a354a35 // 4a35 = 18997 = round(1.164 * 64 * 256)
|
||||||
pslld xmm4, 24
|
|
||||||
mov eax, 0x04ad04ad // 04ad = 1197 = round(1.164 * 64 * 16)
|
|
||||||
movd xmm3, eax
|
|
||||||
pshufd xmm3, xmm3, 0
|
|
||||||
mov eax, 0x4a7f4a7f // 4a7f = 19071 = round(1.164 * 64 * 256)
|
|
||||||
movd xmm2, eax
|
movd xmm2, eax
|
||||||
pshufd xmm2, xmm2,0
|
pshufd xmm2, xmm2,0
|
||||||
|
mov eax, 0x04880488 // 0488 = 1160 = round(1.164 * 64 * 16)
|
||||||
|
movd xmm3, eax
|
||||||
|
pshufd xmm3, xmm3, 0
|
||||||
|
pcmpeqb xmm4, xmm4 // generate mask 0xff000000
|
||||||
|
pslld xmm4, 24
|
||||||
|
|
||||||
mov eax, [esp + 4] // Y
|
mov eax, [esp + 4] // Y
|
||||||
mov edx, [esp + 8] // rgb
|
mov edx, [esp + 8] // rgb
|
||||||
@ -2348,6 +2348,7 @@ void YToARGBRow_SSE2(const uint8* y_buf,
|
|||||||
|
|
||||||
#ifdef HAS_YTOARGBROW_AVX2
|
#ifdef HAS_YTOARGBROW_AVX2
|
||||||
// 16 pixels of Y converted to 16 pixels of ARGB (64 bytes).
|
// 16 pixels of Y converted to 16 pixels of ARGB (64 bytes).
|
||||||
|
// note: vpunpcklbw mutates and vpackuswb unmutates.
|
||||||
__declspec(naked) __declspec(align(16))
|
__declspec(naked) __declspec(align(16))
|
||||||
void YToARGBRow_AVX2(const uint8* y_buf,
|
void YToARGBRow_AVX2(const uint8* y_buf,
|
||||||
uint8* rgb_buf,
|
uint8* rgb_buf,
|
||||||
@ -2355,10 +2356,10 @@ void YToARGBRow_AVX2(const uint8* y_buf,
|
|||||||
__asm {
|
__asm {
|
||||||
vpcmpeqb ymm4, ymm4, ymm4 // generate mask 0xff000000
|
vpcmpeqb ymm4, ymm4, ymm4 // generate mask 0xff000000
|
||||||
vpslld ymm4, ymm4, 24
|
vpslld ymm4, ymm4, 24
|
||||||
mov eax, 0x04ad04ad // 04ad = 1197 = round(1.164 * 64 * 16)
|
mov eax, 0x04880488 // 0488 = 1160 = round(1.164 * 64 * 16)
|
||||||
vmovd xmm3, eax
|
vmovd xmm3, eax
|
||||||
vbroadcastss ymm3, xmm3
|
vbroadcastss ymm3, xmm3
|
||||||
mov eax, 0x4a7f4a7f // 4a7f = 19071 = round(1.164 * 64 * 256)
|
mov eax, 0x4a354a35 // 4a35 = 18997 = round(1.164 * 64 * 256)
|
||||||
vmovd xmm2, eax
|
vmovd xmm2, eax
|
||||||
vbroadcastss ymm2, xmm2
|
vbroadcastss ymm2, xmm2
|
||||||
|
|
||||||
@ -2370,7 +2371,7 @@ void YToARGBRow_AVX2(const uint8* y_buf,
|
|||||||
// Step 1: Scale Y contribution to 16 G values. G = (y - 16) * 1.164
|
// Step 1: Scale Y contribution to 16 G values. G = (y - 16) * 1.164
|
||||||
vmovdqu xmm0, [eax]
|
vmovdqu xmm0, [eax]
|
||||||
lea eax, [eax + 16]
|
lea eax, [eax + 16]
|
||||||
vpermq ymm0, ymm0, 0xd8
|
vpermq ymm0, ymm0, 0xd8 // vpunpcklbw mutates
|
||||||
vpunpcklbw ymm0, ymm0, ymm0 // Y.Y
|
vpunpcklbw ymm0, ymm0, ymm0 // Y.Y
|
||||||
vpmulhuw ymm0, ymm0, ymm2
|
vpmulhuw ymm0, ymm0, ymm2
|
||||||
vpsubusw ymm0, ymm0, ymm3
|
vpsubusw ymm0, ymm0, ymm3
|
||||||
@ -2381,8 +2382,8 @@ void YToARGBRow_AVX2(const uint8* y_buf,
|
|||||||
// Step 2: Weave into ARGB
|
// Step 2: Weave into ARGB
|
||||||
vpunpcklbw ymm1, ymm0, ymm0 // GG - mutates
|
vpunpcklbw ymm1, ymm0, ymm0 // GG - mutates
|
||||||
vpermq ymm1, ymm1, 0xd8
|
vpermq ymm1, ymm1, 0xd8
|
||||||
vpunpcklwd ymm0, ymm1, ymm1 // GGGG first 4 pixels
|
vpunpcklwd ymm0, ymm1, ymm1 // GGGG first 8 pixels
|
||||||
vpunpckhwd ymm1, ymm1, ymm1 // GGGG next 4 pixels
|
vpunpckhwd ymm1, ymm1, ymm1 // GGGG next 8 pixels
|
||||||
vpor ymm0, ymm0, ymm4
|
vpor ymm0, ymm0, ymm4
|
||||||
vpor ymm1, ymm1, ymm4
|
vpor ymm1, ymm1, ymm4
|
||||||
vmovdqu [edx], ymm0
|
vmovdqu [edx], ymm0
|
||||||
@ -2396,7 +2397,6 @@ void YToARGBRow_AVX2(const uint8* y_buf,
|
|||||||
}
|
}
|
||||||
#endif // HAS_YTOARGBROW_AVX2
|
#endif // HAS_YTOARGBROW_AVX2
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAS_MIRRORROW_SSSE3
|
#ifdef HAS_MIRRORROW_SSSE3
|
||||||
// Shuffle table for reversing the bytes.
|
// Shuffle table for reversing the bytes.
|
||||||
static const uvec8 kShuffleMirror = {
|
static const uvec8 kShuffleMirror = {
|
||||||
|
|||||||
@ -227,7 +227,7 @@ TEST_F(libyuvTest, TestYUV) {
|
|||||||
EXPECT_EQ(255, b0);
|
EXPECT_EQ(255, b0);
|
||||||
|
|
||||||
YUVToRGB(240, 255, 0, &r1, &g1, &b1);
|
YUVToRGB(240, 255, 0, &r1, &g1, &b1);
|
||||||
EXPECT_NEAR(56, r1, 1);
|
EXPECT_EQ(57, r1);
|
||||||
EXPECT_EQ(255, g1);
|
EXPECT_EQ(255, g1);
|
||||||
EXPECT_EQ(255, b1);
|
EXPECT_EQ(255, b1);
|
||||||
|
|
||||||
@ -238,9 +238,9 @@ TEST_F(libyuvTest, TestYUV) {
|
|||||||
EXPECT_EQ(2, b0);
|
EXPECT_EQ(2, b0);
|
||||||
|
|
||||||
YUVToRGB(240, 0, 0, &r1, &g1, &b1);
|
YUVToRGB(240, 0, 0, &r1, &g1, &b1);
|
||||||
EXPECT_NEAR(56, r1, 1);
|
EXPECT_EQ(57, r1);
|
||||||
EXPECT_EQ(255, g1);
|
EXPECT_EQ(255, g1);
|
||||||
EXPECT_NEAR(6, b1, 1);
|
EXPECT_EQ(5, b1);
|
||||||
|
|
||||||
for (int i = 0; i < 256; ++i) {
|
for (int i = 0; i < 256; ++i) {
|
||||||
YUVToRGBReference(i, 128, 128, &r0, &g0, &b0);
|
YUVToRGBReference(i, 128, 128, &r0, &g0, &b0);
|
||||||
@ -281,9 +281,9 @@ TEST_F(libyuvTest, TestGreyYUV) {
|
|||||||
YUVToRGBReference(y, 128, 128, &r0, &g0, &b0);
|
YUVToRGBReference(y, 128, 128, &r0, &g0, &b0);
|
||||||
YUVToRGB(y, 128, 128, &r1, &g1, &b1);
|
YUVToRGB(y, 128, 128, &r1, &g1, &b1);
|
||||||
YToRGB(y, &r2, &g2, &b2);
|
YToRGB(y, &r2, &g2, &b2);
|
||||||
EXPECT_NEAR(r0, r1, ERROR_R);
|
EXPECT_EQ(r0, r1);
|
||||||
EXPECT_NEAR(g0, g1, ERROR_G);
|
EXPECT_EQ(g0, g1);
|
||||||
EXPECT_NEAR(b0, b1, ERROR_B);
|
EXPECT_EQ(b0, b1);
|
||||||
EXPECT_EQ(r1, r2);
|
EXPECT_EQ(r1, r2);
|
||||||
EXPECT_EQ(g1, g2);
|
EXPECT_EQ(g1, g2);
|
||||||
EXPECT_EQ(b1, b2);
|
EXPECT_EQ(b1, b2);
|
||||||
|
|||||||
@ -1262,7 +1262,7 @@ TEST_F(libyuvTest, TestYToARGB) {
|
|||||||
argb[i * 4 + 3]);
|
argb[i * 4 + 3]);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 32; ++i) {
|
for (int i = 0; i < 32; ++i) {
|
||||||
EXPECT_NEAR(expectedg[i], argb[i * 4 + 0], 1);
|
EXPECT_EQ(expectedg[i], argb[i * 4 + 0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user