Commit 85869c87 authored by fbarchard@google.com's avatar fbarchard@google.com

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
parent b4a1182f
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]);
......
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