aboutsummaryrefslogtreecommitdiff
path: root/source/convert_from.cc
diff options
context:
space:
mode:
authorFrank Barchard <fbarchard@chromium.org>2017-12-12 14:53:10 -0800
committerCommit Bot <commit-bot@chromium.org>2017-12-12 23:40:58 +0000
commitbb3180ae807ddf55335926d5f53b3856e2882b1c (patch)
treef629ca39b3b0e784b15485c79c9d9b48e9f8a79b /source/convert_from.cc
parentc3677514309ca27d3f8ffb22272a9b699e544131 (diff)
downloadlibyuv-bb3180ae807ddf55335926d5f53b3856e2882b1c.tar.gz
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>
Diffstat (limited to 'source/convert_from.cc')
-rw-r--r--source/convert_from.cc129
1 files changed, 125 insertions, 4 deletions
diff --git a/source/convert_from.cc b/source/convert_from.cc
index 0f52f9ef..509fe232 100644
--- a/source/convert_from.cc
+++ b/source/convert_from.cc
@@ -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,