Index: remoting/base/util_unittest.cc |
diff --git a/remoting/base/util_unittest.cc b/remoting/base/util_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..24e628daf19064d66e36df7391626a4609dbda28 |
--- /dev/null |
+++ b/remoting/base/util_unittest.cc |
@@ -0,0 +1,187 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <algorithm> |
+ |
+#include "remoting/base/util.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+#include "third_party/skia/include/core/SkRect.h" |
+#include "third_party/skia/include/core/SkSize.h" |
+ |
+static const int kWidth = 32 ; |
+static const int kHeight = 24 ; |
+static const int kBytesPerPixel = 4; |
+static const int kYStride = kWidth; |
+static const int kUvStride = kWidth / 2; |
+static const int kRgbStride = kWidth * kBytesPerPixel; |
+static const uint32 kFillColor = 0xffffff; |
+ |
+namespace remoting { |
+ |
+class YuvToRgbTester { |
+ public: |
+ YuvToRgbTester() { |
+ yuv_buffer_size_ = (kYStride + kUvStride) * kHeight; |
+ yuv_buffer_.reset(new uint8[yuv_buffer_size_]); |
+ yplane_ = yuv_buffer_.get(); |
+ uplane_ = yplane_ + (kYStride * kHeight); |
+ vplane_ = uplane_ + (kUvStride * kHeight / 2); |
+ |
+ rgb_buffer_size_ = kWidth * kHeight * kBytesPerPixel; |
+ rgb_buffer_.reset(new uint8[rgb_buffer_size_]); |
+ |
+ ResetYuvBuffer(); |
+ ResetRgbBuffer(); |
+ } |
+ |
+ ~YuvToRgbTester() {} |
+ |
+ void ResetYuvBuffer() { |
+ memset(yuv_buffer_.get(), 0, yuv_buffer_size_); |
+ } |
+ |
+ void ResetRgbBuffer() { |
+ memset(rgb_buffer_.get(), 0, rgb_buffer_size_); |
+ } |
+ |
+ void FillRgbBuffer(const SkIRect& rect) { |
+ uint32* ptr = reinterpret_cast<uint32*>( |
+ rgb_buffer_.get() + (rect.top() * kRgbStride) + |
+ (rect.left() * kBytesPerPixel)); |
+ int width = rect.width(); |
+ for (int height = rect.height(); height > 0; --height) { |
+ std::fill(ptr, ptr + width, kFillColor); |
+ ptr += kRgbStride / kBytesPerPixel; |
+ } |
+ } |
+ |
+ // Check the the desination buffer is filled within expected bounds. |
+ void CheckRgbBuffer(const SkIRect& rect) { |
+ uint32* ptr = reinterpret_cast<uint32*>(rgb_buffer_.get()); |
+ for (int y = 0; y < kHeight; ++y) { |
+ if (y < rect.top() || rect.bottom() <= y) { |
+ // The whole line should be intact. |
+ EXPECT_EQ((ptrdiff_t)kWidth, |
+ std::count(ptr, ptr + kWidth, 0u)); |
+ } else { |
+ // The space before the painted rectangle should be intact. |
+ EXPECT_EQ((ptrdiff_t)rect.left(), |
+ std::count(ptr, ptr + rect.left(), 0u)); |
+ |
+ // All pixels of the target rectangle should be touched. |
+ EXPECT_EQ(ptr + rect.right(), |
+ std::find(ptr + rect.left(), ptr + rect.right(), 0u)); |
+ |
+ // The space after the painted rectangle should be intact. |
+ EXPECT_EQ((ptrdiff_t)kWidth - rect.right(), |
+ std::count(ptr + rect.right(), ptr + kWidth, 0u)); |
+ } |
+ ptr += kRgbStride / kBytesPerPixel; |
+ } |
+ } |
+ |
+ void RunTest(const SkISize dest_size, const SkIRect& rect) { |
+ ASSERT_TRUE(SkIRect::MakeSize(dest_size).contains(rect)); |
+ |
+ // Reset buffers. |
+ ResetYuvBuffer(); |
+ ResetRgbBuffer(); |
+ FillRgbBuffer(rect); |
+ |
+ // RGB -> YUV |
+ ConvertRGB32ToYUVWithRect(rgb_buffer_.get(), |
+ yplane_, |
+ uplane_, |
+ vplane_, |
+ 0, |
+ 0, |
+ kWidth, |
+ kHeight, |
+ kRgbStride, |
+ kYStride, |
+ kUvStride); |
+ |
+ // Reset RGB buffer and do opposite conversion. |
+ ResetRgbBuffer(); |
+ ConvertAndScaleYUVToRGB32Rect(yplane_, |
+ uplane_, |
+ vplane_, |
+ kYStride, |
+ kUvStride, |
+ SkISize::Make(kWidth, kHeight), |
+ SkIRect::MakeWH(kWidth, kHeight), |
+ rgb_buffer_.get(), |
+ kRgbStride, |
+ dest_size, |
+ SkIRect::MakeSize(dest_size), |
+ rect); |
+ |
+ // Check if it worked out. |
+ CheckRgbBuffer(rect); |
+ } |
+ |
+ void TestBasicConversion() { |
+ // Whole buffer. |
+ RunTest(SkISize::Make(kWidth, kHeight), SkIRect::MakeWH(kWidth, kHeight)); |
+ } |
+ |
+ private: |
+ size_t yuv_buffer_size_; |
+ scoped_array<uint8> yuv_buffer_; |
+ uint8* yplane_; |
+ uint8* uplane_; |
+ uint8* vplane_; |
+ |
+ size_t rgb_buffer_size_; |
+ scoped_array<uint8> rgb_buffer_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(YuvToRgbTester); |
+}; |
+ |
+TEST(YuvToRgbTest, BasicConversion) { |
+ YuvToRgbTester tester; |
+ tester.TestBasicConversion(); |
+} |
+ |
+TEST(YuvToRgbTest, Clipping) { |
+ YuvToRgbTester tester; |
+ |
+ SkISize dest_size = SkISize::Make(kWidth, kHeight); |
+ SkIRect rect = SkIRect::MakeLTRB(0, 0, kWidth - 1, kHeight - 1); |
+ for (int i = 0; i < 16; ++i) { |
+ SkIRect dest_rect = rect; |
+ if ((i & 1) != 0) |
+ dest_rect.fLeft += 1; |
+ if ((i & 2) != 0) |
+ dest_rect.fTop += 1; |
+ if ((i & 4) != 0) |
+ dest_rect.fRight += 1; |
+ if ((i & 8) != 0) |
+ dest_rect.fBottom += 1; |
+ |
+ tester.RunTest(dest_size, dest_rect); |
+ } |
+} |
+ |
+TEST(YuvToRgbTest, ClippingAndScaling) { |
+ YuvToRgbTester tester; |
+ |
+ SkISize dest_size = SkISize::Make(kWidth - 10, kHeight - 10); |
+ SkIRect rect = SkIRect::MakeLTRB(5, 5, kWidth - 11, kHeight - 11); |
+ for (int i = 0; i < 16; ++i) { |
+ SkIRect dest_rect = rect; |
+ if ((i & 1) != 0) |
+ dest_rect.fLeft += 1; |
+ if ((i & 2) != 0) |
+ dest_rect.fTop += 1; |
+ if ((i & 4) != 0) |
+ dest_rect.fRight += 1; |
+ if ((i & 8) != 0) |
+ dest_rect.fBottom += 1; |
+ |
+ tester.RunTest(dest_size, dest_rect); |
+ } |
+} |
+ |
+} // namespace remoting |