Fix YToARGB and tweaks to thresholds in YUV tests.
BUG=411
TESTED=libyuvTest.TestYToARGB
R=bcornell@google.com

Review URL: https://webrtc-codereview.appspot.com/44709004

git-svn-id: http://libyuv.googlecode.com/svn/trunk@1330 16f28f9a-4ce2-e073-06de-1de4eb20be90
diff --git a/README.chromium b/README.chromium
index f020f8f..36ac6fb 100644
--- a/README.chromium
+++ b/README.chromium
@@ -1,6 +1,6 @@
 Name: libyuv
 URL: http://code.google.com/p/libyuv/
-Version: 1325
+Version: 1330
 License: BSD
 License File: LICENSE
 
diff --git a/include/libyuv/version.h b/include/libyuv/version.h
index aa63831..bb5d938 100644
--- a/include/libyuv/version.h
+++ b/include/libyuv/version.h
@@ -11,6 +11,6 @@
 #ifndef INCLUDE_LIBYUV_VERSION_H_  // NOLINT
 #define INCLUDE_LIBYUV_VERSION_H_
 
-#define LIBYUV_VERSION 1325
+#define LIBYUV_VERSION 1330
 
 #endif  // INCLUDE_LIBYUV_VERSION_H_  NOLINT
diff --git a/source/row_common.cc b/source/row_common.cc
index 1a2a211..12500d8 100644
--- a/source/row_common.cc
+++ b/source/row_common.cc
@@ -1027,9 +1027,9 @@
 // C reference code that mimics the YUV assembly.
 static __inline void YPixel(uint8 y, uint8* b, uint8* g, uint8* r) {
   uint32 y1 = (uint32)(y * 0x0101 * YG) >> 16;
-  *b = Clamp((int32)(y1 - YGB) >> 6);
-  *g = Clamp((int32)(y1 - YGB) >> 6);
-  *r = Clamp((int32)(y1 - YGB) >> 6);
+  *b = Clamp((int32)(y1 + YGB) >> 6);
+  *g = Clamp((int32)(y1 + YGB) >> 6);
+  *r = Clamp((int32)(y1 + YGB) >> 6);
 }
 
 #undef YG
diff --git a/unit_test/color_test.cc b/unit_test/color_test.cc
index 844a6a0..0dd2989 100644
--- a/unit_test/color_test.cc
+++ b/unit_test/color_test.cc
@@ -23,13 +23,11 @@
 // TODO(fbarchard): Port high accuracy YUV to RGB to Neon.
 #if !defined(LIBYUV_DISABLE_NEON) && \
     (defined(__aarch64__) || defined(__ARM_NEON__) || defined(LIBYUV_NEON))
-#define MAX_CDIFF 0
 #define ERROR_R 1
 #define ERROR_G 1
 #define ERROR_B 3
 #define ERROR_FULL 6
 #else
-#define MAX_CDIFF 0
 #define ERROR_R 1
 #define ERROR_G 1
 #define ERROR_B 3
@@ -131,12 +129,10 @@
   free_aligned_buffer_64(dst_pixels_c);                                        \
 }                                                                              \
 
-// TODO(fbarchard): Reduce C to Opt diff to 0.
-TESTCS(TestI420, I420ToARGB, ARGBToI420, 1, 2, benchmark_width_,
-       ERROR_FULL, MAX_CDIFF)
-TESTCS(TestI422, I422ToARGB, ARGBToI422, 0, 1, 0, ERROR_FULL, MAX_CDIFF)
-TESTCS(TestJ420, J420ToARGB, ARGBToJ420, 1, 2, benchmark_width_, 1, 0)
-TESTCS(TestJ422, J422ToARGB, ARGBToJ422, 0, 1, 0, 1, 0)
+TESTCS(TestI420, I420ToARGB, ARGBToI420, 1, 2, benchmark_width_, ERROR_FULL, 0)
+TESTCS(TestI422, I422ToARGB, ARGBToI422, 0, 1, 0, ERROR_FULL, 0)
+TESTCS(TestJ420, J420ToARGB, ARGBToJ420, 1, 2, benchmark_width_, 3, 0)
+TESTCS(TestJ422, J422ToARGB, ARGBToJ422, 0, 1, 0, 3, 0)
 
 static void YUVToRGB(int y, int u, int v, int* r, int* g, int* b) {
   const int kWidth = 16;
@@ -147,7 +143,7 @@
   SIMD_ALIGNED(uint8 orig_y[16]);
   SIMD_ALIGNED(uint8 orig_u[8]);
   SIMD_ALIGNED(uint8 orig_v[8]);
-  SIMD_ALIGNED(uint8 orig_pixels[16 * 1 * 4]);
+  SIMD_ALIGNED(uint8 orig_pixels[16 * 4]);
   memset(orig_y, y, kPixels);
   memset(orig_u, u, kHalfPixels);
   memset(orig_v, v, kHalfPixels);
@@ -173,7 +169,7 @@
   SIMD_ALIGNED(uint8 orig_y[16]);
   SIMD_ALIGNED(uint8 orig_u[8]);
   SIMD_ALIGNED(uint8 orig_v[8]);
-  SIMD_ALIGNED(uint8 orig_pixels[16 * 1 * 4]);
+  SIMD_ALIGNED(uint8 orig_pixels[16 * 4]);
   memset(orig_y, y, kPixels);
   memset(orig_u, u, kHalfPixels);
   memset(orig_v, v, kHalfPixels);
@@ -196,13 +192,28 @@
   const int kPixels = kWidth * kHeight;
 
   SIMD_ALIGNED(uint8 orig_y[16]);
-  SIMD_ALIGNED(uint8 orig_pixels[16 * 1 * 4]);
+  SIMD_ALIGNED(uint8 orig_pixels[16 * 4]);
   memset(orig_y, y, kPixels);
 
   /* YUV converted to ARGB. */
-  YToARGB(orig_y, kWidth,
-          orig_pixels, kWidth * 4,
-          kWidth, kHeight);
+  YToARGB(orig_y, kWidth, orig_pixels, kWidth * 4, kWidth, kHeight);
+
+  *b = orig_pixels[0];
+  *g = orig_pixels[1];
+  *r = orig_pixels[2];
+}
+
+static void YJToRGB(int y, int* r, int* g, int* b) {
+  const int kWidth = 16;
+  const int kHeight = 1;
+  const int kPixels = kWidth * kHeight;
+
+  SIMD_ALIGNED(uint8 orig_y[16]);
+  SIMD_ALIGNED(uint8 orig_pixels[16 * 4]);
+  memset(orig_y, y, kPixels);
+
+  /* YUV converted to ARGB. */
+  I400ToARGB(orig_y, kWidth, orig_pixels, kWidth * 4, kWidth, kHeight);
 
   *b = orig_pixels[0];
   *g = orig_pixels[1];
@@ -211,15 +222,15 @@
 
 // Pick a method for clamping.
 #define CLAMPMETHOD_IF 1
-//#define CLAMPMETHOD_TABLE 1
-//#define CLAMPMETHOD_TERNARY 1
-//#define CLAMPMETHOD_MASK 1
+//  #define CLAMPMETHOD_TABLE 1
+//  #define CLAMPMETHOD_TERNARY 1
+//  #define CLAMPMETHOD_MASK 1
 
 // Pick a method for rounding.
 #define ROUND(f) static_cast<int>(f + 0.5)
-//#define ROUND(f) lrintf(f)
-//#define ROUND(f) static_cast<int>(round(f))
-//#define ROUND(f) _mm_cvt_ss2si(_mm_load_ss(&f))
+//  #define ROUND(f) lrintf(f)
+//  #define ROUND(f) static_cast<int>(round(f))
+//  #define ROUND(f) _mm_cvt_ss2si(_mm_load_ss(&f))
 
 #if defined(CLAMPMETHOD_IF)
 static int RoundToByte(float f) {
@@ -516,4 +527,53 @@
   printf("\n");
 }
 
+TEST_F(libyuvTest, TestGreyYUVJ) {
+  int r0, g0, b0, r1, g1, b1, r2, g2, b2;
+
+  // black
+  YUVJToRGBReference(0, 128, 128, &r0, &g0, &b0);
+  EXPECT_EQ(0, r0);
+  EXPECT_EQ(0, g0);
+  EXPECT_EQ(0, b0);
+
+  YUVJToRGB(0, 128, 128, &r1, &g1, &b1);
+  EXPECT_EQ(0, r1);
+  EXPECT_EQ(0, g1);
+  EXPECT_EQ(0, b1);
+
+  // white
+  YUVJToRGBReference(255, 128, 128, &r0, &g0, &b0);
+  EXPECT_EQ(255, r0);
+  EXPECT_EQ(255, g0);
+  EXPECT_EQ(255, b0);
+
+  YUVJToRGB(255, 128, 128, &r1, &g1, &b1);
+  EXPECT_EQ(255, r1);
+  EXPECT_EQ(255, g1);
+  EXPECT_EQ(255, b1);
+
+  // grey
+  YUVJToRGBReference(128, 128, 128, &r0, &g0, &b0);
+  EXPECT_EQ(128, r0);
+  EXPECT_EQ(128, g0);
+  EXPECT_EQ(128, b0);
+
+  YUVJToRGB(128, 128, 128, &r1, &g1, &b1);
+  EXPECT_EQ(128, r1);
+  EXPECT_EQ(128, g1);
+  EXPECT_EQ(128, b1);
+
+  for (int y = 0; y < 256; ++y) {
+    YUVJToRGBReference(y, 128, 128, &r0, &g0, &b0);
+    YUVJToRGB(y, 128, 128, &r1, &g1, &b1);
+    YJToRGB(y, &r2, &g2, &b2);
+    EXPECT_EQ(r0, r1);
+    EXPECT_EQ(g0, g1);
+    EXPECT_EQ(b0, b1);
+    EXPECT_EQ(r0, r2);
+    EXPECT_EQ(g0, g2);
+    EXPECT_EQ(b0, b2);
+  }
+}
+
 }  // namespace libyuv