mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-07 09:16:48 +08:00
Add I420ToAR30 10 bit RGB
For more complete support of AR30 format, add I420ToAR30 allowing the new RGB 10 bit format to be used from standard 8 bit I420 format. Bug: libyuv:751 Test: I420ToAR30 unittest added Change-Id: Ia8b0857447408bd6adab485158ce5f38d6dc2faa Reviewed-on: https://chromium-review.googlesource.com/823243 Reviewed-by: Weiyong Yao <braveyao@chromium.org> Commit-Queue: Frank Barchard <fbarchard@chromium.org>
This commit is contained in:
parent
c367751430
commit
bb3180ae80
@ -276,6 +276,18 @@ int I420ToARGB4444(const uint8* src_y,
|
||||
int dst_stride_frame,
|
||||
int width,
|
||||
int height);
|
||||
// Convert I420 to AR30.
|
||||
LIBYUV_API
|
||||
int I420ToAR30(const uint8* src_y,
|
||||
int src_stride_y,
|
||||
const uint8* src_u,
|
||||
int src_stride_u,
|
||||
const uint8* src_v,
|
||||
int src_stride_v,
|
||||
uint8* dst_ar30,
|
||||
int dst_stride_ar30,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
// Convert I420 to specified format.
|
||||
// "dst_sample_stride" is bytes in a row for the destination. Pass 0 if the
|
||||
|
||||
@ -1125,6 +1125,122 @@ int I420ToRGB565Dither(const uint8* src_y,
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert I420 to AR30 with matrix
|
||||
static int I420ToAR30Matrix(const uint8* src_y,
|
||||
int src_stride_y,
|
||||
const uint8* src_u,
|
||||
int src_stride_u,
|
||||
const uint8* src_v,
|
||||
int src_stride_v,
|
||||
uint8* dst_ar30,
|
||||
int dst_stride_ar30,
|
||||
const struct YuvConstants* yuvconstants,
|
||||
int width,
|
||||
int height) {
|
||||
int y;
|
||||
void (*I422ToARGBRow)(const uint8* y_buf, const uint8* u_buf,
|
||||
const uint8* v_buf, uint8* rgb_buf,
|
||||
const struct YuvConstants* yuvconstants, int width) =
|
||||
I422ToARGBRow_C;
|
||||
void (*ARGBToAR30Row)(const uint8* src_argb, uint8* dst_rgb, int width) =
|
||||
ARGBToAR30Row_C;
|
||||
|
||||
if (!src_y || !src_u || !src_v || !dst_ar30 || width <= 0 || height == 0) {
|
||||
return -1;
|
||||
}
|
||||
// Negative height means invert the image.
|
||||
if (height < 0) {
|
||||
height = -height;
|
||||
dst_ar30 = dst_ar30 + (height - 1) * dst_stride_ar30;
|
||||
dst_stride_ar30 = -dst_stride_ar30;
|
||||
}
|
||||
|
||||
#if defined(HAS_ARGBTOAR30ROW_SSSE3)
|
||||
if (TestCpuFlag(kCpuHasSSSE3)) {
|
||||
ARGBToAR30Row = ARGBToAR30Row_Any_SSSE3;
|
||||
if (IS_ALIGNED(width, 4)) {
|
||||
ARGBToAR30Row = ARGBToAR30Row_SSSE3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_ARGBTOAR30ROW_AVX2)
|
||||
if (TestCpuFlag(kCpuHasAVX2)) {
|
||||
ARGBToAR30Row = ARGBToAR30Row_Any_AVX2;
|
||||
if (IS_ALIGNED(width, 8)) {
|
||||
ARGBToAR30Row = ARGBToAR30Row_AVX2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_I422TOARGBROW_SSSE3)
|
||||
if (TestCpuFlag(kCpuHasSSSE3)) {
|
||||
I422ToARGBRow = I422ToARGBRow_Any_SSSE3;
|
||||
if (IS_ALIGNED(width, 8)) {
|
||||
I422ToARGBRow = I422ToARGBRow_SSSE3;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_I422TOARGBROW_AVX2)
|
||||
if (TestCpuFlag(kCpuHasAVX2)) {
|
||||
I422ToARGBRow = I422ToARGBRow_Any_AVX2;
|
||||
if (IS_ALIGNED(width, 16)) {
|
||||
I422ToARGBRow = I422ToARGBRow_AVX2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_I422TOARGBROW_NEON)
|
||||
if (TestCpuFlag(kCpuHasNEON)) {
|
||||
I422ToARGBRow = I422ToARGBRow_Any_NEON;
|
||||
if (IS_ALIGNED(width, 8)) {
|
||||
I422ToARGBRow = I422ToARGBRow_NEON;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(HAS_I422TOARGBROW_MSA)
|
||||
if (TestCpuFlag(kCpuHasMSA)) {
|
||||
I422ToARGBRow = I422ToARGBRow_Any_MSA;
|
||||
if (IS_ALIGNED(width, 8)) {
|
||||
I422ToARGBRow = I422ToARGBRow_MSA;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
// Row buffer for ARGB.
|
||||
align_buffer_64(row_argb, width * 4);
|
||||
|
||||
for (y = 0; y < height; ++y) {
|
||||
I422ToARGBRow(src_y, src_u, src_v, row_argb, yuvconstants, width);
|
||||
ARGBToAR30Row(row_argb, dst_ar30, width);
|
||||
dst_ar30 += dst_stride_ar30;
|
||||
src_y += src_stride_y;
|
||||
if (y & 1) {
|
||||
src_u += src_stride_u;
|
||||
src_v += src_stride_v;
|
||||
}
|
||||
}
|
||||
|
||||
free_aligned_buffer_64(row_argb);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert I420 to AR30.
|
||||
LIBYUV_API
|
||||
int I420ToAR30(const uint8* src_y,
|
||||
int src_stride_y,
|
||||
const uint8* src_u,
|
||||
int src_stride_u,
|
||||
const uint8* src_v,
|
||||
int src_stride_v,
|
||||
uint8* dst_ar30,
|
||||
int dst_stride_ar30,
|
||||
int width,
|
||||
int height) {
|
||||
return I420ToAR30Matrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
|
||||
src_stride_v, dst_ar30, dst_stride_ar30,
|
||||
&kYuvI601Constants, width, height);
|
||||
}
|
||||
|
||||
// Convert I420 to specified format
|
||||
LIBYUV_API
|
||||
int ConvertFromI420(const uint8* y,
|
||||
@ -1157,8 +1273,8 @@ int ConvertFromI420(const uint8* y,
|
||||
break;
|
||||
case FOURCC_RGBP:
|
||||
r = I420ToRGB565(y, y_stride, u, u_stride, v, v_stride, dst_sample,
|
||||
dst_sample_stride ? dst_sample_stride : width * 2, width,
|
||||
height);
|
||||
dst_sample_stride ? dst_sample_stride : width * 2,
|
||||
width, height);
|
||||
break;
|
||||
case FOURCC_RGBO:
|
||||
r = I420ToARGB1555(y, y_stride, u, u_stride, v, v_stride, dst_sample,
|
||||
@ -1172,8 +1288,8 @@ int ConvertFromI420(const uint8* y,
|
||||
break;
|
||||
case FOURCC_24BG:
|
||||
r = I420ToRGB24(y, y_stride, u, u_stride, v, v_stride, dst_sample,
|
||||
dst_sample_stride ? dst_sample_stride : width * 3, width,
|
||||
height);
|
||||
dst_sample_stride ? dst_sample_stride : width * 3,
|
||||
width, height);
|
||||
break;
|
||||
case FOURCC_RAW:
|
||||
r = I420ToRAW(y, y_stride, u, u_stride, v, v_stride, dst_sample,
|
||||
@ -1200,6 +1316,11 @@ int ConvertFromI420(const uint8* y,
|
||||
dst_sample_stride ? dst_sample_stride : width * 4, width,
|
||||
height);
|
||||
break;
|
||||
case FOURCC_AR30:
|
||||
r = I420ToAR30(y, y_stride, u, u_stride, v, v_stride, dst_sample,
|
||||
dst_sample_stride ? dst_sample_stride : width * 4, width,
|
||||
height);
|
||||
break;
|
||||
case FOURCC_I400:
|
||||
r = I400Copy(y, y_stride, dst_sample,
|
||||
dst_sample_stride ? dst_sample_stride : width, width,
|
||||
|
||||
@ -802,8 +802,7 @@ void ARGBToAR30Row_AVX2(const uint8* src, uint8* dst, int width) {
|
||||
"m"(kMaskRB10), // %5
|
||||
"m"(kMaskAG10), // %6
|
||||
"m"(kMulAG10) // %7
|
||||
: "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5",
|
||||
"xmm6");
|
||||
: "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -30,6 +30,9 @@
|
||||
|
||||
namespace libyuv {
|
||||
|
||||
// Alias to copy pixels as is
|
||||
#define AR30ToAR30 ARGBCopy
|
||||
|
||||
#define SUBSAMPLE(v, a) ((((v) + (a)-1)) / (a))
|
||||
|
||||
#define TESTPLANARTOPI(SRC_FMT_PLANAR, SRC_SUBSAMP_X, SRC_SUBSAMP_Y, \
|
||||
@ -597,6 +600,7 @@ TESTPLANARTOB(I422, 2, 1, YUY2, 2, 4, 1, 0, ARGB, 4)
|
||||
TESTPLANARTOB(I422, 2, 1, UYVY, 2, 4, 1, 0, ARGB, 4)
|
||||
TESTPLANARTOB(I420, 2, 2, I400, 1, 1, 1, 0, ARGB, 4)
|
||||
TESTPLANARTOB(J420, 2, 2, J400, 1, 1, 1, 0, ARGB, 4)
|
||||
TESTPLANARTOB(I420, 2, 2, AR30, 4, 4, 1, 0, AR30, 4)
|
||||
|
||||
#define TESTQPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
|
||||
YALIGN, W1280, DIFF, N, NEG, OFF, ATTEN) \
|
||||
@ -1967,9 +1971,6 @@ TEST_F(LibYUVConvertTest, ARGBToAR30Row_Opt) {
|
||||
}
|
||||
#endif // HAS_ARGBTOAR30ROW_AVX2
|
||||
|
||||
// Alias to copy pixels as is
|
||||
#define AR30ToAR30 ARGBToARGB
|
||||
|
||||
#define TESTPLANAR16TOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, \
|
||||
ALIGN, YALIGN, W1280, DIFF, N, NEG, SOFF, DOFF, \
|
||||
FMT_C, BPP_C) \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user