diff options
author | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-09 19:00:51 +0000 |
---|---|---|
committer | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-09 19:00:51 +0000 |
commit | b3ca1f55f4a1f0dd84c72e99e60a971cebe33b1f (patch) | |
tree | 5602448fb7a33a0d19f570f49a7cba13a6275b7c /remoting/base/util_unittest.cc | |
parent | be2394928af63719c56cd97fb2725ab4123e10ce (diff) | |
download | chromium_src-b3ca1f55f4a1f0dd84c72e99e60a971cebe33b1f.zip chromium_src-b3ca1f55f4a1f0dd84c72e99e60a971cebe33b1f.tar.gz chromium_src-b3ca1f55f4a1f0dd84c72e99e60a971cebe33b1f.tar.bz2 |
Introducing helper wrappers for copying a rectangle from a one partial buffer to another. YUV to RGB and RGB to RGB operations are supported. YUV to RGB allows down-scaling of re
This CL also adds a supression for Valgrind which otherwise falsely complains about accessing uninitialized memory. See 113076 for details.
BUG=109938,113076
TEST=remoting_unittests.Yuv2Rgb
Review URL: http://codereview.chromium.org/9371002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@121258 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/base/util_unittest.cc')
-rw-r--r-- | remoting/base/util_unittest.cc | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/remoting/base/util_unittest.cc b/remoting/base/util_unittest.cc new file mode 100644 index 0000000..24e628d --- /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 |