mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-06 08:46:47 +08:00
UYVYToARGB and ARGBToRGB565 added for more ARGB support completeness.
BUG=38 TEST=none Review URL: https://webrtc-codereview.appspot.com/624004 git-svn-id: http://libyuv.googlecode.com/svn/trunk@275 16f28f9a-4ce2-e073-06de-1de4eb20be90
This commit is contained in:
parent
b4a1182ffd
commit
85869c87f3
@ -1,6 +1,6 @@
|
||||
Name: libyuv
|
||||
URL: http://code.google.com/p/libyuv/
|
||||
Version: 274
|
||||
Version: 275
|
||||
License: BSD
|
||||
License File: LICENSE
|
||||
|
||||
|
||||
@ -57,6 +57,11 @@ int YUY2ToARGB(const uint8* src_yuy2, int src_stride_yuy2,
|
||||
uint8* dst_argb, int dst_stride_argb,
|
||||
int width, int height);
|
||||
|
||||
// Convert UYVY to ARGB.
|
||||
int UYVYToARGB(const uint8* src_uyvy, int src_stride_uyvy,
|
||||
uint8* dst_argb, int dst_stride_argb,
|
||||
int width, int height);
|
||||
|
||||
// Convert I422 to ARGB.
|
||||
int I422ToARGB(const uint8* src_y, int src_stride_y,
|
||||
const uint8* src_u, int src_stride_u,
|
||||
@ -101,6 +106,7 @@ int ABGRToARGB(const uint8* src_abgr, int src_stride_abgr,
|
||||
|
||||
// Palindromes.
|
||||
#define ARGBToBGRA BGRAToARGB
|
||||
#define ARGBToABGR ABGRToARGB
|
||||
|
||||
// Convert BGRA to ARGB. Also used for ARGB to BGRA.
|
||||
int BGRAToARGB(const uint8* src_bgra, int src_stride_bgra,
|
||||
@ -117,6 +123,11 @@ int ARGBToRAW(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_rgb, int dst_stride_rgb,
|
||||
int width, int height);
|
||||
|
||||
// Convert ARGB To RGB565.
|
||||
int ARGBToRGB565(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_rgb565, int dst_stride_rgb565,
|
||||
int width, int height);
|
||||
|
||||
// Convert ARGB to I400.
|
||||
int ARGBToI400(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_y, int dst_stride_y,
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
#ifndef INCLUDE_LIBYUV_VERSION_H_
|
||||
#define INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
#define LIBYUV_VERSION 274
|
||||
#define LIBYUV_VERSION 275
|
||||
|
||||
#endif // INCLUDE_LIBYUV_VERSION_H_
|
||||
|
||||
|
||||
@ -539,6 +539,38 @@ int ARGBToRAW(const uint8* src_argb, int src_stride_argb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert ARGB To RGB565.
|
||||
int ARGBToRGB565(const uint8* src_argb, int src_stride_argb,
|
||||
uint8* dst_rgb565, int dst_stride_rgb565,
|
||||
int width, int height) {
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
src_argb = src_argb + (height - 1) * src_stride_argb;
|
||||
src_stride_argb = -src_stride_argb;
|
||||
}
|
||||
void (*ARGBToRGB565Row)(const uint8* src_argb, uint8* dst_rgb, int pix) =
|
||||
ARGBToRGB565Row_C;
|
||||
#if defined(HAS_ARGBTORGB565ROW_SSSE3)
|
||||
if (TestCpuFlag(kCpuHasSSSE3) &&
|
||||
IS_ALIGNED(src_argb, 16) && IS_ALIGNED(src_stride_argb, 16)) {
|
||||
if (width * 3 <= kMaxStride) {
|
||||
ARGBToRGB565Row = ARGBToRGB565Row_Any_SSSE3;
|
||||
}
|
||||
if (IS_ALIGNED(width, 16) &&
|
||||
IS_ALIGNED(dst_rgb565, 16) && IS_ALIGNED(dst_stride_rgb565, 16)) {
|
||||
ARGBToRGB565Row = ARGBToRGB565Row_SSSE3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
ARGBToRGB565Row(src_argb, dst_rgb565, width);
|
||||
src_argb += src_stride_argb;
|
||||
dst_rgb565 += dst_stride_rgb565;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert NV12 to ARGB.
|
||||
int NV12ToARGB(const uint8* src_y, int src_stride_y,
|
||||
const uint8* src_uv, int src_stride_uv,
|
||||
@ -665,6 +697,72 @@ int YUY2ToARGB(const uint8* src_yuy2, int src_stride_yuy2,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert UYVY to ARGB.
|
||||
int UYVYToARGB(const uint8* src_uyvy, int src_stride_uyvy,
|
||||
uint8* dst_argb, int dst_stride_argb,
|
||||
int width, int height) {
|
||||
// Negative height means invert the image.
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy;
|
||||
src_stride_uyvy = -src_stride_uyvy;
|
||||
}
|
||||
void (*UYVYToUVRow)(const uint8* src_uyvy, int src_stride_uyvy,
|
||||
uint8* dst_u, uint8* dst_v, int pix) = UYVYToUVRow_C;
|
||||
void (*UYVYToYRow)(const uint8* src_uyvy,
|
||||
uint8* dst_y, int pix) = UYVYToYRow_C;
|
||||
#if defined(HAS_UYVYTOYROW_SSE2)
|
||||
if (TestCpuFlag(kCpuHasSSE2)) {
|
||||
if (width > 16) {
|
||||
UYVYToUVRow = UYVYToUVRow_Any_SSE2;
|
||||
UYVYToYRow = UYVYToYRow_Any_SSE2;
|
||||
}
|
||||
if (IS_ALIGNED(width, 16)) {
|
||||
UYVYToUVRow = UYVYToUVRow_Unaligned_SSE2;
|
||||
UYVYToYRow = UYVYToYRow_Unaligned_SSE2;
|
||||
if (IS_ALIGNED(src_uyvy, 16) && IS_ALIGNED(src_stride_uyvy, 16)) {
|
||||
UYVYToUVRow = UYVYToUVRow_SSE2;
|
||||
UYVYToYRow = UYVYToYRow_SSE2;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void (*I420ToARGBRow)(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
const uint8* v_buf,
|
||||
uint8* argb_buf,
|
||||
int width) = I420ToARGBRow_C;
|
||||
#if defined(HAS_I420TOARGBROW_NEON)
|
||||
if (TestCpuFlag(kCpuHasNEON)) {
|
||||
I420ToARGBRow = I420ToARGBRow_Any_NEON;
|
||||
if (IS_ALIGNED(width, 16)) {
|
||||
I420ToARGBRow = I420ToARGBRow_NEON;
|
||||
}
|
||||
}
|
||||
#elif defined(HAS_I420TOARGBROW_SSSE3)
|
||||
if (TestCpuFlag(kCpuHasSSSE3) && width >= 8) {
|
||||
I420ToARGBRow = I420ToARGBRow_Any_SSSE3;
|
||||
if (IS_ALIGNED(width, 8) &&
|
||||
IS_ALIGNED(dst_argb, 16) && IS_ALIGNED(dst_stride_argb, 16)) {
|
||||
I420ToARGBRow = I420ToARGBRow_SSSE3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SIMD_ALIGNED(uint8 rowy[kMaxStride]);
|
||||
SIMD_ALIGNED(uint8 rowu[kMaxStride]);
|
||||
SIMD_ALIGNED(uint8 rowv[kMaxStride]);
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
UYVYToUVRow(src_uyvy, src_stride_uyvy, rowu, rowv, width);
|
||||
UYVYToYRow(src_uyvy, rowy, width);
|
||||
I420ToARGBRow(rowy, rowu, rowv, dst_argb, width);
|
||||
src_uyvy += src_stride_uyvy;
|
||||
dst_argb += dst_stride_argb;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert NV12 to RGB565.
|
||||
int NV12ToRGB565(const uint8* src_y, int src_stride_y,
|
||||
const uint8* src_uv, int src_stride_uv,
|
||||
|
||||
@ -110,10 +110,10 @@ void ARGB1555ToARGBRow_C(const uint8* src_rgb, uint8* dst_argb, int width) {
|
||||
|
||||
void ARGB4444ToARGBRow_C(const uint8* src_rgb, uint8* dst_argb, int width) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
uint8 a = src_rgb[1] >> 4;
|
||||
uint8 r = src_rgb[1] & 0x0f;
|
||||
uint8 g = src_rgb[0] >> 4;
|
||||
uint8 b = src_rgb[0] & 0x0f;
|
||||
uint8 g = src_rgb[0] >> 4;
|
||||
uint8 r = src_rgb[1] & 0x0f;
|
||||
uint8 a = src_rgb[1] >> 4;
|
||||
dst_argb[0] = (b << 4) | b;
|
||||
dst_argb[1] = (g << 4) | g;
|
||||
dst_argb[2] = (r << 4) | r;
|
||||
@ -166,7 +166,7 @@ void ARGBToARGB1555Row_C(const uint8* src_argb, uint8* dst_rgb, int width) {
|
||||
uint8 b = src_argb[0] >> 3;
|
||||
uint8 g = src_argb[1] >> 3;
|
||||
uint8 r = src_argb[2] >> 3;
|
||||
uint8 a = src_argb[2] >> 7;
|
||||
uint8 a = src_argb[3] >> 7;
|
||||
*reinterpret_cast<uint16*>(dst_rgb) = (a << 15) | (r << 10) | (g << 5) | b;
|
||||
dst_rgb += 2;
|
||||
src_argb += 4;
|
||||
@ -178,7 +178,7 @@ void ARGBToARGB4444Row_C(const uint8* src_argb, uint8* dst_rgb, int width) {
|
||||
uint8 b = src_argb[0] >> 4;
|
||||
uint8 g = src_argb[1] >> 4;
|
||||
uint8 r = src_argb[2] >> 4;
|
||||
uint8 a = src_argb[2] >> 4;
|
||||
uint8 a = src_argb[3] >> 4;
|
||||
*reinterpret_cast<uint16*>(dst_rgb) = (a << 12) | (r << 8) | (g << 4) | b;
|
||||
dst_rgb += 2;
|
||||
src_argb += 4;
|
||||
|
||||
@ -94,16 +94,19 @@ TEST_F(libyuvTest, I420To##FMT##_CvsOPT) { \
|
||||
dst_rgb_c, src_width * BPP, \
|
||||
src_width, src_height); \
|
||||
MaskCpuFlags(-1); \
|
||||
I420To##FMT(src_y, src_width, \
|
||||
src_u, src_width >> 1, \
|
||||
src_v, src_width >> 1, \
|
||||
dst_rgb_opt, src_width * BPP, \
|
||||
src_width, src_height); \
|
||||
const int runs = 1000; \
|
||||
for (int i = 0; i < runs; ++i) { \
|
||||
I420To##FMT(src_y, src_width, \
|
||||
src_u, src_width >> 1, \
|
||||
src_v, src_width >> 1, \
|
||||
dst_rgb_opt, src_width * BPP, \
|
||||
src_width, src_height); \
|
||||
} \
|
||||
int err = 0; \
|
||||
for (int i = 0; i < src_height; ++i) { \
|
||||
for (int j = 0; j < src_width * BPP; ++j) { \
|
||||
int diff = static_cast<int>(dst_rgb_c[i * src_width * BPP + j]) - \
|
||||
static_cast<int>(dst_rgb_opt[i * src_width * BPP + j]); \
|
||||
int diff = static_cast<int>(dst_rgb_c[i * src_width * BPP + j]) - \
|
||||
static_cast<int>(dst_rgb_opt[i * src_width * BPP + j]); \
|
||||
if (abs(diff) > 2) \
|
||||
err++; \
|
||||
} \
|
||||
@ -122,34 +125,36 @@ TESTI420TO(ABGR, 4)
|
||||
TESTI420TO(RAW, 3)
|
||||
TESTI420TO(RGB24, 3)
|
||||
TESTI420TO(RGB565, 2)
|
||||
// TODO(fbarchard): Add 555/4444 unittests once passing.
|
||||
//TESTI420TO(ARGB1555, 2)
|
||||
//TESTI420TO(ARGB4444, 2)
|
||||
TESTI420TO(ARGB1555, 2)
|
||||
TESTI420TO(ARGB4444, 2)
|
||||
|
||||
#define TESTARGBTO(FMT, BPP) \
|
||||
TEST_F(libyuvTest, ARGBTo##FMT##_CvsOPT) { \
|
||||
#define TESTATOB(FMT_A, BPP_A, FMT_B, BPP_B) \
|
||||
TEST_F(libyuvTest, ##FMT_A##To##FMT_B##_CvsOPT) { \
|
||||
const int src_width = 1280; \
|
||||
const int src_height = 720; \
|
||||
align_buffer_16(src_argb, src_width * src_height * 4); \
|
||||
align_buffer_16(dst_rgb_c, (src_width * BPP) * src_height); \
|
||||
align_buffer_16(dst_rgb_opt, (src_width * BPP) * src_height); \
|
||||
align_buffer_16(src_argb, src_width * src_height * BPP_A); \
|
||||
align_buffer_16(dst_rgb_c, (src_width * BPP_B) * src_height); \
|
||||
align_buffer_16(dst_rgb_opt, (src_width * BPP_B) * src_height); \
|
||||
srandom(time(NULL)); \
|
||||
for (int i = 0; i < src_height; ++i) \
|
||||
for (int j = 0; j < src_width * 4; ++j) \
|
||||
src_argb[(i * src_width * 4) + j] = (random() & 0xff); \
|
||||
for (int j = 0; j < src_width * BPP_A; ++j) \
|
||||
src_argb[(i * src_width * BPP_A) + j] = (random() & 0xff); \
|
||||
MaskCpuFlags(kCpuInitialized); \
|
||||
ARGBTo##FMT(src_argb, src_width * 4, \
|
||||
dst_rgb_c, src_width * BPP, \
|
||||
##FMT_A##To##FMT_B(src_argb, src_width * BPP_A, \
|
||||
dst_rgb_c, src_width * BPP_B, \
|
||||
src_width, src_height); \
|
||||
MaskCpuFlags(-1); \
|
||||
ARGBTo##FMT(src_argb, src_width * 4, \
|
||||
dst_rgb_opt, src_width * BPP, \
|
||||
src_width, src_height); \
|
||||
const int runs = 1000; \
|
||||
for (int i = 0; i < runs; ++i) { \
|
||||
##FMT_A##To##FMT_B(src_argb, src_width * BPP_A, \
|
||||
dst_rgb_opt, src_width * BPP_B, \
|
||||
src_width, src_height); \
|
||||
} \
|
||||
int err = 0; \
|
||||
for (int i = 0; i < src_height; ++i) { \
|
||||
for (int j = 0; j < src_width * BPP; ++j) { \
|
||||
int diff = static_cast<int>(dst_rgb_c[i * src_width * BPP + j]) - \
|
||||
static_cast<int>(dst_rgb_opt[i * src_width * BPP + j]); \
|
||||
for (int j = 0; j < src_width * BPP_B; ++j) { \
|
||||
int diff = static_cast<int>(dst_rgb_c[i * src_width * BPP_B + j]) - \
|
||||
static_cast<int>(dst_rgb_opt[i * src_width * BPP_B + j]); \
|
||||
if (abs(diff) > 2) \
|
||||
err++; \
|
||||
} \
|
||||
@ -160,14 +165,17 @@ TEST_F(libyuvTest, ARGBTo##FMT##_CvsOPT) { \
|
||||
free_aligned_buffer_16(dst_rgb_opt) \
|
||||
}
|
||||
|
||||
// TODO(fbarchard): Expose all ARGBToRGB functions and test.
|
||||
//TESTARGBTO(BGRA, 4)
|
||||
//TESTARGBTO(ABGR, 4)
|
||||
TESTARGBTO(RAW, 3)
|
||||
TESTARGBTO(RGB24, 3)
|
||||
//TESTARGBTO(RGB565, 2)
|
||||
//TESTARGBTO(ARGB1555, 2)
|
||||
//TESTARGBTO(ARGB4444, 2)
|
||||
// TODO(fbarchard): Expose more ARGBToRGB functions and test.
|
||||
TESTATOB(ARGB, 4, BGRA, 4)
|
||||
TESTATOB(ARGB, 4, ABGR, 4)
|
||||
TESTATOB(ARGB, 4, RAW, 3)
|
||||
TESTATOB(ARGB, 4, RGB24, 3)
|
||||
TESTATOB(ARGB, 4, RGB565, 2)
|
||||
//TESTATOB(ARGB, 4, ARGB1555, 2)
|
||||
//TESTATOB(ARGB, 4, ARGB4444, 2)
|
||||
|
||||
TESTATOB(YUY2, 2, ARGB, 4)
|
||||
TESTATOB(UYVY, 2, ARGB, 4)
|
||||
|
||||
TEST_F(libyuvTest, TestAttenuate) {
|
||||
SIMD_ALIGNED(uint8 orig_pixels[256][4]);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user