mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-06 16:56:55 +08:00
Add RGBColorTable which is like ARGBColorTable but only does first 3 channels.
BUG=none TEST=none R=dingkai@google.com, thorcarpenter@google.com, wuwang@google.com Review URL: https://webrtc-codereview.appspot.com/1858004 git-svn-id: http://libyuv.googlecode.com/svn/trunk@739 16f28f9a-4ce2-e073-06de-1de4eb20be90
This commit is contained in:
parent
cd52054ce8
commit
5520710ef7
@ -1,6 +1,6 @@
|
|||||||
Name: libyuv
|
Name: libyuv
|
||||||
URL: http://code.google.com/p/libyuv/
|
URL: http://code.google.com/p/libyuv/
|
||||||
Version: 738
|
Version: 739
|
||||||
License: BSD
|
License: BSD
|
||||||
License File: LICENSE
|
License File: LICENSE
|
||||||
|
|
||||||
|
|||||||
@ -203,6 +203,13 @@ int ARGBColorTable(uint8* dst_argb, int dst_stride_argb,
|
|||||||
const uint8* table_argb,
|
const uint8* table_argb,
|
||||||
int x, int y, int width, int height);
|
int x, int y, int width, int height);
|
||||||
|
|
||||||
|
// Apply a color table each ARGB pixel but preserve destination alpha.
|
||||||
|
// Table contains 256 ARGB values.
|
||||||
|
LIBYUV_API
|
||||||
|
int RGBColorTable(uint8* dst_argb, int dst_stride_argb,
|
||||||
|
const uint8* table_argb,
|
||||||
|
int x, int y, int width, int height);
|
||||||
|
|
||||||
// Quantize a rectangle of ARGB. Alpha unaffected.
|
// Quantize a rectangle of ARGB. Alpha unaffected.
|
||||||
// scale is a 16 bit fractional fixed point scaler between 0 and 65535.
|
// scale is a 16 bit fractional fixed point scaler between 0 and 65535.
|
||||||
// interval_size should be a value between 1 and 255.
|
// interval_size should be a value between 1 and 255.
|
||||||
|
|||||||
@ -28,7 +28,7 @@ extern "C" {
|
|||||||
|
|
||||||
#if defined(__CLR_VER) || defined(COVERAGE_ENABLED) || \
|
#if defined(__CLR_VER) || defined(COVERAGE_ENABLED) || \
|
||||||
defined(TARGET_IPHONE_SIMULATOR) || \
|
defined(TARGET_IPHONE_SIMULATOR) || \
|
||||||
defined(__native_client__) && defined(__x86_64__)
|
(defined(__native_client__) && defined(__x86_64__))
|
||||||
#define LIBYUV_DISABLE_X86
|
#define LIBYUV_DISABLE_X86
|
||||||
#endif
|
#endif
|
||||||
// True if compiling for SSSE3 as a requirement.
|
// True if compiling for SSSE3 as a requirement.
|
||||||
@ -132,6 +132,7 @@ extern "C" {
|
|||||||
// TODO(fbarchard): Port to gcc.
|
// TODO(fbarchard): Port to gcc.
|
||||||
#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER)
|
#if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER)
|
||||||
#define HAS_ARGBCOLORTABLEROW_X86
|
#define HAS_ARGBCOLORTABLEROW_X86
|
||||||
|
#define HAS_RGBCOLORTABLEROW_X86
|
||||||
// Visual C 2012 required for AVX2.
|
// Visual C 2012 required for AVX2.
|
||||||
#if _MSC_VER >= 1700
|
#if _MSC_VER >= 1700
|
||||||
#define HAS_ARGBSHUFFLEROW_AVX2
|
#define HAS_ARGBSHUFFLEROW_AVX2
|
||||||
@ -1426,6 +1427,9 @@ void ARGBColorMatrixRow_NEON(uint8* dst_argb, const int8* matrix_argb,
|
|||||||
void ARGBColorTableRow_C(uint8* dst_argb, const uint8* table_argb, int width);
|
void ARGBColorTableRow_C(uint8* dst_argb, const uint8* table_argb, int width);
|
||||||
void ARGBColorTableRow_X86(uint8* dst_argb, const uint8* table_argb, int width);
|
void ARGBColorTableRow_X86(uint8* dst_argb, const uint8* table_argb, int width);
|
||||||
|
|
||||||
|
void RGBColorTableRow_C(uint8* dst_argb, const uint8* table_argb, int width);
|
||||||
|
void RGBColorTableRow_X86(uint8* dst_argb, const uint8* table_argb, int width);
|
||||||
|
|
||||||
void ARGBQuantizeRow_C(uint8* dst_argb, int scale, int interval_size,
|
void ARGBQuantizeRow_C(uint8* dst_argb, int scale, int interval_size,
|
||||||
int interval_offset, int width);
|
int interval_offset, int width);
|
||||||
void ARGBQuantizeRow_SSE2(uint8* dst_argb, int scale, int interval_size,
|
void ARGBQuantizeRow_SSE2(uint8* dst_argb, int scale, int interval_size,
|
||||||
|
|||||||
@ -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 738
|
#define LIBYUV_VERSION 739
|
||||||
|
|
||||||
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
|
#endif // INCLUDE_LIBYUV_VERSION_H_ NOLINT
|
||||||
|
|||||||
@ -1413,6 +1413,38 @@ int ARGBColorTable(uint8* dst_argb, int dst_stride_argb,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply a color table each ARGB pixel but preserve destination alpha.
|
||||||
|
// Table contains 256 ARGB values.
|
||||||
|
LIBYUV_API
|
||||||
|
int RGBColorTable(uint8* dst_argb, int dst_stride_argb,
|
||||||
|
const uint8* table_argb,
|
||||||
|
int dst_x, int dst_y, int width, int height) {
|
||||||
|
if (!dst_argb || !table_argb || width <= 0 || height <= 0 ||
|
||||||
|
dst_x < 0 || dst_y < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// Coalesce contiguous rows.
|
||||||
|
if (dst_stride_argb == width * 4) {
|
||||||
|
return RGBColorTable(dst_argb, dst_stride_argb,
|
||||||
|
table_argb,
|
||||||
|
dst_x, dst_y,
|
||||||
|
width * height, 1);
|
||||||
|
}
|
||||||
|
void (*RGBColorTableRow)(uint8* dst_argb, const uint8* table_argb,
|
||||||
|
int width) = RGBColorTableRow_C;
|
||||||
|
#if defined(HAS_RGBCOLORTABLEROW_X86)
|
||||||
|
if (TestCpuFlag(kCpuHasX86)) {
|
||||||
|
RGBColorTableRow = RGBColorTableRow_X86;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
uint8* dst = dst_argb + dst_y * dst_stride_argb + dst_x * 4;
|
||||||
|
for (int y = 0; y < height; ++y) {
|
||||||
|
RGBColorTableRow(dst, table_argb, width);
|
||||||
|
dst += dst_stride_argb;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// ARGBQuantize is used to posterize art.
|
// ARGBQuantize is used to posterize art.
|
||||||
// e.g. rgb / qvalue * qvalue + qvalue / 2
|
// e.g. rgb / qvalue * qvalue + qvalue / 2
|
||||||
// But the low levels implement efficiently with 3 parameters, and could be
|
// But the low levels implement efficiently with 3 parameters, and could be
|
||||||
|
|||||||
@ -688,6 +688,19 @@ void ARGBColorTableRow_C(uint8* dst_argb, const uint8* table_argb, int width) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply color table to a row of image.
|
||||||
|
void RGBColorTableRow_C(uint8* dst_argb, const uint8* table_argb, int width) {
|
||||||
|
for (int x = 0; x < width; ++x) {
|
||||||
|
int b = dst_argb[0];
|
||||||
|
int g = dst_argb[1];
|
||||||
|
int r = dst_argb[2];
|
||||||
|
dst_argb[0] = table_argb[b * 4 + 0];
|
||||||
|
dst_argb[1] = table_argb[g * 4 + 1];
|
||||||
|
dst_argb[2] = table_argb[r * 4 + 2];
|
||||||
|
dst_argb += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ARGBQuantizeRow_C(uint8* dst_argb, int scale, int interval_size,
|
void ARGBQuantizeRow_C(uint8* dst_argb, int scale, int interval_size,
|
||||||
int interval_offset, int width) {
|
int interval_offset, int width) {
|
||||||
for (int x = 0; x < width; ++x) {
|
for (int x = 0; x < width; ++x) {
|
||||||
|
|||||||
@ -5138,6 +5138,49 @@ void ARGBColorTableRow_X86(uint8* dst_argb, const uint8* table_argb,
|
|||||||
}
|
}
|
||||||
#endif // HAS_ARGBCOLORTABLEROW_X86
|
#endif // HAS_ARGBCOLORTABLEROW_X86
|
||||||
|
|
||||||
|
#ifdef HAS_RGBCOLORTABLEROW_X86
|
||||||
|
// Tranform RGB pixels with color table.
|
||||||
|
__declspec(naked) __declspec(align(16))
|
||||||
|
void RGBColorTableRow_X86(uint8* dst_argb, const uint8* table_argb, int width) {
|
||||||
|
__asm {
|
||||||
|
push ebx
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
push ebp
|
||||||
|
mov eax, [esp + 16 + 4] /* dst_argb */
|
||||||
|
mov edi, [esp + 16 + 8] /* table_argb */
|
||||||
|
mov ecx, [esp + 16 + 12] /* width */
|
||||||
|
xor ebx, ebx
|
||||||
|
xor edx, edx
|
||||||
|
|
||||||
|
align 16
|
||||||
|
convertloop:
|
||||||
|
mov ebp, dword ptr [eax] // BGRA
|
||||||
|
mov esi, ebp
|
||||||
|
and ebp, 255
|
||||||
|
shr esi, 8
|
||||||
|
and esi, 255
|
||||||
|
mov bl, [edi + ebp * 4 + 0] // B
|
||||||
|
mov dl, [edi + esi * 4 + 1] // G
|
||||||
|
mov ebp, dword ptr [eax] // BGRA
|
||||||
|
shr ebp, 16
|
||||||
|
and ebp, 255
|
||||||
|
mov [eax], bl
|
||||||
|
mov [eax + 1], dl
|
||||||
|
mov bl, [edi + ebp * 4 + 2] // R
|
||||||
|
mov [eax + 2], bl
|
||||||
|
lea eax, [eax + 4]
|
||||||
|
sub ecx, 1
|
||||||
|
jg convertloop
|
||||||
|
pop ebp
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
pop ebx
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // HAS_RGBCOLORTABLEROW_X86
|
||||||
|
|
||||||
#ifdef HAS_ARGBQUANTIZEROW_SSE2
|
#ifdef HAS_ARGBQUANTIZEROW_SSE2
|
||||||
// Quantize 4 ARGB pixels (16 bytes).
|
// Quantize 4 ARGB pixels (16 bytes).
|
||||||
// Aligned to 16 bytes.
|
// Aligned to 16 bytes.
|
||||||
|
|||||||
@ -596,6 +596,65 @@ TEST_F(libyuvTest, TestARGBColorTable) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Same as TestARGBColorTable except alpha does not change.
|
||||||
|
TEST_F(libyuvTest, TestRGBColorTable) {
|
||||||
|
SIMD_ALIGNED(uint8 orig_pixels[256][4]);
|
||||||
|
memset(orig_pixels, 0, sizeof(orig_pixels));
|
||||||
|
|
||||||
|
// Matrix for Sepia.
|
||||||
|
static const uint8 kARGBTable[256 * 4] = {
|
||||||
|
1u, 2u, 3u, 4u,
|
||||||
|
5u, 6u, 7u, 8u,
|
||||||
|
9u, 10u, 11u, 12u,
|
||||||
|
13u, 14u, 15u, 16u,
|
||||||
|
};
|
||||||
|
|
||||||
|
orig_pixels[0][0] = 0u;
|
||||||
|
orig_pixels[0][1] = 0u;
|
||||||
|
orig_pixels[0][2] = 0u;
|
||||||
|
orig_pixels[0][3] = 0u;
|
||||||
|
orig_pixels[1][0] = 1u;
|
||||||
|
orig_pixels[1][1] = 1u;
|
||||||
|
orig_pixels[1][2] = 1u;
|
||||||
|
orig_pixels[1][3] = 1u;
|
||||||
|
orig_pixels[2][0] = 2u;
|
||||||
|
orig_pixels[2][1] = 2u;
|
||||||
|
orig_pixels[2][2] = 2u;
|
||||||
|
orig_pixels[2][3] = 2u;
|
||||||
|
orig_pixels[3][0] = 0u;
|
||||||
|
orig_pixels[3][1] = 1u;
|
||||||
|
orig_pixels[3][2] = 2u;
|
||||||
|
orig_pixels[3][3] = 3u;
|
||||||
|
// Do 16 to test asm version.
|
||||||
|
RGBColorTable(&orig_pixels[0][0], 0, &kARGBTable[0], 0, 0, 16, 1);
|
||||||
|
EXPECT_EQ(1u, orig_pixels[0][0]);
|
||||||
|
EXPECT_EQ(2u, orig_pixels[0][1]);
|
||||||
|
EXPECT_EQ(3u, orig_pixels[0][2]);
|
||||||
|
EXPECT_EQ(0u, orig_pixels[0][3]); // Alpha unchanged.
|
||||||
|
EXPECT_EQ(5u, orig_pixels[1][0]);
|
||||||
|
EXPECT_EQ(6u, orig_pixels[1][1]);
|
||||||
|
EXPECT_EQ(7u, orig_pixels[1][2]);
|
||||||
|
EXPECT_EQ(1u, orig_pixels[1][3]); // Alpha unchanged.
|
||||||
|
EXPECT_EQ(9u, orig_pixels[2][0]);
|
||||||
|
EXPECT_EQ(10u, orig_pixels[2][1]);
|
||||||
|
EXPECT_EQ(11u, orig_pixels[2][2]);
|
||||||
|
EXPECT_EQ(2u, orig_pixels[2][3]); // Alpha unchanged.
|
||||||
|
EXPECT_EQ(1u, orig_pixels[3][0]);
|
||||||
|
EXPECT_EQ(6u, orig_pixels[3][1]);
|
||||||
|
EXPECT_EQ(11u, orig_pixels[3][2]);
|
||||||
|
EXPECT_EQ(3u, orig_pixels[3][3]); // Alpha unchanged.
|
||||||
|
|
||||||
|
for (int i = 0; i < 256; ++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_div256_; ++i) {
|
||||||
|
RGBColorTable(&orig_pixels[0][0], 0, &kARGBTable[0], 0, 0, 256, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(libyuvTest, TestARGBQuantize) {
|
TEST_F(libyuvTest, TestARGBQuantize) {
|
||||||
SIMD_ALIGNED(uint8 orig_pixels[256][4]);
|
SIMD_ALIGNED(uint8 orig_pixels[256][4]);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user