Commit b38b73d8 authored by fbarchard@google.com's avatar fbarchard@google.com

ARGBLumaColorTable function.

BUG=267
TEST=Luma*
R=thorcarpenter@google.com

Review URL: https://webrtc-codereview.appspot.com/2202004

git-svn-id: http://libyuv.googlecode.com/svn/trunk@783 16f28f9a-4ce2-e073-06de-1de4eb20be90
parent c3c06ec3
Name: libyuv
URL: http://code.google.com/p/libyuv/
Version: 782
Version: 783
License: BSD
License File: LICENSE
......
......@@ -210,6 +210,15 @@ int RGBColorTable(uint8* dst_argb, int dst_stride_argb,
const uint8* table_argb,
int x, int y, int width, int height);
// Apply a luma/color table each ARGB pixel but preserve destination alpha.
// Table contains 32768 values indexed by [Y][C] where 7 it 7 bit luma from
// RGB (YJ style) and C is an 8 bit color component (R, G or B).
LIBYUV_API
int ARGBLumaColorTable(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb, int dst_stride_argb,
const uint8* luma_rgb_table,
int width, int height);
// Apply a 3 term polynomial to ARGB values.
// poly points to a 4x4 matrix. The first row is constants. The 2nd row is
// coefficients for b, g, r and a. The 3rd row is coefficients for b squared,
......
......@@ -144,6 +144,7 @@ extern "C" {
#define HAS_ARGBCOLORTABLEROW_X86
#define HAS_ARGBPOLYNOMIALROW_SSE2
#define HAS_RGBCOLORTABLEROW_X86
#define HAS_ARGBLUMACOLORTABLEROW_SSE2
// Caveat: Visual C 2012 required for AVX2.
#if _MSC_VER >= 1700
......@@ -1554,8 +1555,15 @@ void ARGBPolynomialRow_SSE2(const uint8* src_argb,
uint8* dst_argb, const float* poly,
int width);
void ARGBPolynomialRow_AVX2(const uint8* src_argb,
uint8* dst_argb, const float* poly,
int width);
uint8* dst_argb, const float* poly,
int width);
void ARGBLumaColorTableRow_C(const uint8* src_argb,
uint8* dst_argb, const uint8* luma,
int width);
void ARGBLumaColorTableRow_SSSE3(const uint8* src_argb,
uint8* dst_argb, const uint8* luma,
int width);
// Divide num by div and return as 16.16 fixed point result.
int FixedDiv_C(int num, int div);
......
......@@ -11,6 +11,6 @@
#ifndef INCLUDE_LIBYUV_VERSION_H_ // NOLINT
#define INCLUDE_LIBYUV_VERSION_H_
#define LIBYUV_VERSION 782
#define LIBYUV_VERSION 783
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
......@@ -2069,6 +2069,38 @@ int ARGBPolynomial(const uint8* src_argb, int src_stride_argb,
return 0;
}
// Apply a lumacolortable to each ARGB pixel.
LIBYUV_API
int ARGBLumaColorTable(const uint8* src_argb, int src_stride_argb,
uint8* dst_argb, int dst_stride_argb,
const uint8* luma,
int width, int height) {
if (!src_argb || !dst_argb || !luma || width <= 0 || height <= 0) {
return -1;
}
// Coalesce contiguous rows.
if (src_stride_argb == width * 4 && dst_stride_argb == width * 4) {
return ARGBLumaColorTable(src_argb, 0,
dst_argb, 0,
luma,
width * height, 1);
}
void (*ARGBLumaColorTableRow)(const uint8* src_argb,
uint8* dst_argb, const uint8* luma,
int width) = ARGBLumaColorTableRow_C;
#if defined(HAS_ARGBLUMACOLORTABLEROW_SSSE3)
if (TestCpuFlag(kCpuHasSSE2) && IS_ALIGNED(width, 2)) {
ARGBLumaColorTableRow = ARGBLumaColorTableRow_SSSE3;
}
#endif
for (int y = 0; y < height; ++y) {
ARGBLumaColorTableRow(src_argb, dst_argb, luma, width);
src_argb += src_stride_argb;
dst_argb += dst_stride_argb;
}
return 0;
}
#ifdef __cplusplus
} // extern "C"
} // namespace libyuv
......
......@@ -2051,6 +2051,39 @@ void ARGBPolynomialRow_C(const uint8* src_argb,
}
}
// RGB to Luminance.
// Leverage the fact that we want shifted left by 8 by the caller.
//
// Borrowed from libyuv/files/source/row_common.cc.
// JPeg 7 bit Y:
// b 0.11400 * 128 = 14.592 = 15
// g 0.58700 * 128 = 75.136 = 75
// r 0.29900 * 128 = 38.272 = 38
static __inline unsigned int RGBToYJx256(uint8 r, uint8 g, uint8 b) {
return (38u * r + 75u * g + 15u * b) & 0x7F00u;
}
void ARGBLumaColorTableRow_C(const uint8* src_argb,
uint8* dst_argb, const uint8* luma,
int width) {
for (int i = 0; i < width - 1; i += 2) {
// Luminance in rows, color values in columns.
const uint8* luma0 = RGBToYJx256(src_argb[2], src_argb[1], src_argb[0]) +
luma;
dst_argb[0] = luma0[src_argb[0]];
dst_argb[1] = luma0[src_argb[1]];
dst_argb[2] = luma0[src_argb[2]];
dst_argb[3] = src_argb[3];
const uint8* luma1 = RGBToYJx256(src_argb[6], src_argb[5], src_argb[4]) +
luma;
dst_argb[4] = luma0[src_argb[4]];
dst_argb[5] = luma0[src_argb[5]];
dst_argb[6] = luma0[src_argb[6]];
dst_argb[7] = src_argb[7];
src_argb += 8;
dst_argb += 8;
}
}
#undef clamp0
#undef clamp255
......
......@@ -1719,5 +1719,67 @@ TEST_F(libyuvTest, TestARGBPolynomial) {
}
}
TEST_F(libyuvTest, TestARGBLumaColorTable) {
SIMD_ALIGNED(uint8 orig_pixels[1280][4]);
SIMD_ALIGNED(uint8 dst_pixels[1280][4]);
SIMD_ALIGNED(uint8 kLumaColorTable[32768]);
int v = 0;
for (int i = 0; i < 32768; ++i) {
kLumaColorTable[i] = v;
v += 3;
}
// Test blue
orig_pixels[0][0] = 255u;
orig_pixels[0][1] = 0u;
orig_pixels[0][2] = 0u;
orig_pixels[0][3] = 128u;
// Test green
orig_pixels[1][0] = 0u;
orig_pixels[1][1] = 255u;
orig_pixels[1][2] = 0u;
orig_pixels[1][3] = 0u;
// Test red
orig_pixels[2][0] = 0u;
orig_pixels[2][1] = 0u;
orig_pixels[2][2] = 255u;
orig_pixels[2][3] = 255u;
// Test color
orig_pixels[3][0] = 16u;
orig_pixels[3][1] = 64u;
orig_pixels[3][2] = 192u;
orig_pixels[3][3] = 224u;
// Do 16 to test asm version.
ARGBLumaColorTable(&orig_pixels[0][0], 0, &dst_pixels[0][0], 0,
&kLumaColorTable[0], 16, 1);
EXPECT_EQ(253u, dst_pixels[0][0]);
EXPECT_EQ(0u, dst_pixels[0][1]);
EXPECT_EQ(0u, dst_pixels[0][2]);
EXPECT_EQ(128u, dst_pixels[0][3]);
EXPECT_EQ(0u, dst_pixels[1][0]);
EXPECT_EQ(253u, dst_pixels[1][1]);
EXPECT_EQ(0u, dst_pixels[1][2]);
EXPECT_EQ(0u, dst_pixels[1][3]);
EXPECT_EQ(0u, dst_pixels[2][0]);
EXPECT_EQ(0u, dst_pixels[2][1]);
EXPECT_EQ(253u, dst_pixels[2][2]);
EXPECT_EQ(255u, dst_pixels[2][3]);
EXPECT_EQ(48u, dst_pixels[3][0]);
EXPECT_EQ(192u, dst_pixels[3][1]);
EXPECT_EQ(64u, dst_pixels[3][2]);
EXPECT_EQ(224u, dst_pixels[3][3]);
for (int i = 0; i < 1280; ++i) {
orig_pixels[i][0] = i;
orig_pixels[i][1] = i / 2;
orig_pixels[i][2] = i / 3;
orig_pixels[i][3] = i;
}
for (int i = 0; i < benchmark_pixels_div1280_; ++i) {
ARGBLumaColorTable(&orig_pixels[0][0], 0, &dst_pixels[0][0], 0,
&kLumaColorTable[0], 1280, 1);
}
}
} // namespace libyuv
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment