From 50f9e618fa4bcb0561622fd709bee5da922b0fd4 Mon Sep 17 00:00:00 2001
From: Frank Barchard <fbarchard@google.com>
Date: Sun, 7 Jan 2018 01:46:52 -0800
Subject: [PATCH] Add H010ToABGR, I010ToABGR and I010ToARGB functions

ABGR output is implemented using the same source code as ARGB, by swapping
the u and v and supplying the mirrored conversion matrix.
ABGR format (RGBA in memory) is popular on Android.

Bug: libyuv:751
Test: H010ToABGR, I010ToABGR and I010ToARGB unittests

Change-Id: I0b5103628c58dcb22a6442c03814d4d5972e0339
Reviewed-on: https://chromium-review.googlesource.com/852985
Commit-Queue: Miguel Casas <mcasas@chromium.org>
Reviewed-by: Miguel Casas <mcasas@chromium.org>
Reviewed-by: Frank Barchard <fbarchard@chromium.org>
---
 README.chromium               |  2 +-
 include/libyuv/convert_argb.h | 39 ++++++++++++++++++++++
 include/libyuv/version.h      |  2 +-
 source/convert_argb.cc        | 61 +++++++++++++++++++++++++++++++++--
 unit_test/convert_test.cc     |  8 +++--
 5 files changed, 105 insertions(+), 7 deletions(-)

diff --git a/README.chromium b/README.chromium
index 89407bab..373e5f75 100644
--- a/README.chromium
+++ b/README.chromium
@@ -1,6 +1,6 @@
 Name: libyuv
 URL: http://code.google.com/p/libyuv/
-Version: 1687
+Version: 1688
 License: BSD
 License File: LICENSE
 
diff --git a/include/libyuv/convert_argb.h b/include/libyuv/convert_argb.h
index 49838ce7..b8b57cb1 100644
--- a/include/libyuv/convert_argb.h
+++ b/include/libyuv/convert_argb.h
@@ -76,6 +76,32 @@ int I010ToARGB(const uint16* src_y,
                int width,
                int height);
 
+// Convert I010 to ARGB.
+LIBYUV_API
+int I010ToARGB(const uint16* src_y,
+               int src_stride_y,
+               const uint16* src_u,
+               int src_stride_u,
+               const uint16* src_v,
+               int src_stride_v,
+               uint8* dst_argb,
+               int dst_stride_argb,
+               int width,
+               int height);
+
+// Convert I010 to ABGR.
+LIBYUV_API
+int I010ToABGR(const uint16* src_y,
+               int src_stride_y,
+               const uint16* src_u,
+               int src_stride_u,
+               const uint16* src_v,
+               int src_stride_v,
+               uint8* dst_abgr,
+               int dst_stride_abgr,
+               int width,
+               int height);
+
 // Convert H010 to ARGB.
 LIBYUV_API
 int H010ToARGB(const uint16* src_y,
@@ -89,6 +115,19 @@ int H010ToARGB(const uint16* src_y,
                int width,
                int height);
 
+// Convert H010 to ABGR.
+LIBYUV_API
+int H010ToABGR(const uint16* src_y,
+               int src_stride_y,
+               const uint16* src_u,
+               int src_stride_u,
+               const uint16* src_v,
+               int src_stride_v,
+               uint8* dst_abgr,
+               int dst_stride_abgr,
+               int width,
+               int height);
+
 // Convert I422 to ARGB.
 LIBYUV_API
 int I422ToARGB(const uint8* src_y,
diff --git a/include/libyuv/version.h b/include/libyuv/version.h
index 5d063952..97595e58 100644
--- a/include/libyuv/version.h
+++ b/include/libyuv/version.h
@@ -11,6 +11,6 @@
 #ifndef INCLUDE_LIBYUV_VERSION_H_
 #define INCLUDE_LIBYUV_VERSION_H_
 
-#define LIBYUV_VERSION 1687
+#define LIBYUV_VERSION 1688
 
 #endif  // INCLUDE_LIBYUV_VERSION_H_
diff --git a/source/convert_argb.cc b/source/convert_argb.cc
index 212d8506..9b93fc15 100644
--- a/source/convert_argb.cc
+++ b/source/convert_argb.cc
@@ -504,7 +504,7 @@ int H010ToAR30(const uint16* src_y,
 }
 
 // Convert 10 bit YUV to ARGB with matrix
-static int H010ToARGBMatrix(const uint16* src_y,
+static int I010ToARGBMatrix(const uint16* src_y,
                             int src_stride_y,
                             const uint16* src_u,
                             int src_stride_u,
@@ -550,6 +550,42 @@ static int H010ToARGBMatrix(const uint16* src_y,
   return 0;
 }
 
+// Convert I010 to ARGB.
+LIBYUV_API
+int I010ToARGB(const uint16* src_y,
+               int src_stride_y,
+               const uint16* src_u,
+               int src_stride_u,
+               const uint16* src_v,
+               int src_stride_v,
+               uint8* dst_argb,
+               int dst_stride_argb,
+               int width,
+               int height) {
+  return I010ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
+                          src_stride_v, dst_argb, dst_stride_argb,
+                          &kYuvI601Constants, width, height);
+}
+
+// Convert I010 to ABGR.
+LIBYUV_API
+int I010ToABGR(const uint16* src_y,
+               int src_stride_y,
+               const uint16* src_u,
+               int src_stride_u,
+               const uint16* src_v,
+               int src_stride_v,
+               uint8* dst_abgr,
+               int dst_stride_abgr,
+               int width,
+               int height) {
+  return I010ToARGBMatrix(src_y, src_stride_y, src_v,
+                          src_stride_v,  // Swap U and V
+                          src_u, src_stride_u, dst_abgr, dst_stride_abgr,
+                          &kYvuI601Constants,  // Use Yvu matrix
+                          width, height);
+}
+
 // Convert H010 to ARGB.
 LIBYUV_API
 int H010ToARGB(const uint16* src_y,
@@ -562,11 +598,30 @@ int H010ToARGB(const uint16* src_y,
                int dst_stride_argb,
                int width,
                int height) {
-  return H010ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
+  return I010ToARGBMatrix(src_y, src_stride_y, src_u, src_stride_u, src_v,
                           src_stride_v, dst_argb, dst_stride_argb,
                           &kYuvH709Constants, width, height);
 }
 
+// Convert H010 to ABGR.
+LIBYUV_API
+int H010ToABGR(const uint16* src_y,
+               int src_stride_y,
+               const uint16* src_u,
+               int src_stride_u,
+               const uint16* src_v,
+               int src_stride_v,
+               uint8* dst_abgr,
+               int dst_stride_abgr,
+               int width,
+               int height) {
+  return I010ToARGBMatrix(src_y, src_stride_y, src_v,
+                          src_stride_v,  // Swap U and V
+                          src_u, src_stride_u, dst_abgr, dst_stride_abgr,
+                          &kYvuH709Constants,  // Use Yvu matrix
+                          width, height);
+}
+
 // Convert I444 to ARGB with matrix
 static int I444ToARGBMatrix(const uint8* src_y,
                             int src_stride_y,
@@ -1398,7 +1453,7 @@ int AR30ToARGB(const uint8* src_ar30,
     src_stride_ar30 = -src_stride_ar30;
   }
   // Coalesce rows.
-  if (src_stride_ar30 == width * 2 && dst_stride_argb == width * 4) {
+  if (src_stride_ar30 == width * 4 && dst_stride_argb == width * 4) {
     width *= height;
     height = 1;
     src_stride_ar30 = dst_stride_argb = 0;
diff --git a/unit_test/convert_test.cc b/unit_test/convert_test.cc
index cbd1dc9b..7d196a1d 100644
--- a/unit_test/convert_test.cc
+++ b/unit_test/convert_test.cc
@@ -593,7 +593,8 @@ 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)
+TESTPLANARTOB(I420, 2, 2, AR30, 4, 4, 1, 0, ARGB, 4)
+// TESTPLANARTOB(I420, 2, 2, AR30, 4, 4, 1, 0, ABGR, 4)
 
 #define TESTQPLANARTOBI(FMT_PLANAR, SUBSAMP_X, SUBSAMP_Y, FMT_B, BPP_B, ALIGN, \
                         YALIGN, W1280, DIFF, N, NEG, OFF, ATTEN)               \
@@ -1943,7 +1944,7 @@ TESTQPLANARTOE(I420Alpha, 2, 2, ABGR, 1, 4, ARGB, 4)
 // Caveat: Destination needs to be 4 bytes
 TESTPLANETOE(ARGB, 1, 4, AR30, 1, 4, ARGB, 4)
 
-// TESTPLANETOE(ARGB, 1, 4, BGRA, 1, 4, ARGB, 4)
+// TESTPLANETOE(ARGB, 1, 4, AR30, 1, 4, ABGR, 4)
 
 TEST_F(LibYUVConvertTest, RotateWithARGBSource) {
   // 2x2 frames
@@ -2084,6 +2085,9 @@ TEST_F(LibYUVConvertTest, ARGBToAR30Row_Opt) {
 
 TESTPLANAR16TOB(H010, 2, 2, AR30, 4, 4, 1, 2, AR30, 4)
 TESTPLANAR16TOB(H010, 2, 2, ARGB, 4, 4, 1, 2, ARGB, 4)
+TESTPLANAR16TOB(H010, 2, 2, ABGR, 4, 4, 1, 2, ARGB, 4)
+TESTPLANAR16TOB(I010, 2, 2, ARGB, 4, 4, 1, 2, ARGB, 4)
+TESTPLANAR16TOB(I010, 2, 2, ABGR, 4, 4, 1, 2, ARGB, 4)
 
 static int Clamp(int y) {
   if (y < 0) {
-- 
2.18.0