cc: Invalidate eviction cache in cases where we remove/add tiles.
[chromium-blink-merge.git] / remoting / base / util_unittest.cc
blob42237f7ddf280b23e8fc4882ca1a4c864acf1e1d
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <algorithm>
7 #include "remoting/base/util.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "third_party/libyuv/include/libyuv/convert_from_argb.h"
10 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
12 static const int kWidth = 32 ;
13 static const int kHeight = 24 ;
14 static const int kBytesPerPixel = 4;
15 static const int kYStride = kWidth;
16 static const int kUvStride = kWidth / 2;
17 static const int kRgbStride = kWidth * kBytesPerPixel;
18 static const uint32 kFillColor = 0xffffff;
20 namespace remoting {
22 class YuvToRgbTester {
23 public:
24 YuvToRgbTester() {
25 yuv_buffer_size_ = (kYStride + kUvStride) * kHeight;
26 yuv_buffer_.reset(new uint8[yuv_buffer_size_]);
27 yplane_ = yuv_buffer_.get();
28 uplane_ = yplane_ + (kYStride * kHeight);
29 vplane_ = uplane_ + (kUvStride * kHeight / 2);
31 rgb_buffer_size_ = kWidth * kHeight * kBytesPerPixel;
32 rgb_buffer_.reset(new uint8[rgb_buffer_size_]);
34 ResetYuvBuffer();
35 ResetRgbBuffer();
38 ~YuvToRgbTester() {}
40 void ResetYuvBuffer() {
41 memset(yuv_buffer_.get(), 0, yuv_buffer_size_);
44 void ResetRgbBuffer() {
45 memset(rgb_buffer_.get(), 0, rgb_buffer_size_);
48 void FillRgbBuffer(const webrtc::DesktopRect& rect) {
49 uint32* ptr = reinterpret_cast<uint32*>(
50 rgb_buffer_.get() + (rect.top() * kRgbStride) +
51 (rect.left() * kBytesPerPixel));
52 int width = rect.width();
53 for (int height = rect.height(); height > 0; --height) {
54 std::fill(ptr, ptr + width, kFillColor);
55 ptr += kRgbStride / kBytesPerPixel;
59 // Check the the desination buffer is filled within expected bounds.
60 void CheckRgbBuffer(const webrtc::DesktopRect& rect) {
61 uint32* ptr = reinterpret_cast<uint32*>(rgb_buffer_.get());
62 for (int y = 0; y < kHeight; ++y) {
63 if (y < rect.top() || rect.bottom() <= y) {
64 // The whole line should be intact.
65 EXPECT_EQ((ptrdiff_t)kWidth,
66 std::count(ptr, ptr + kWidth, 0u));
67 } else {
68 // The space before the painted rectangle should be intact.
69 EXPECT_EQ((ptrdiff_t)rect.left(),
70 std::count(ptr, ptr + rect.left(), 0u));
72 // All pixels of the target rectangle should be touched.
73 EXPECT_EQ(ptr + rect.right(),
74 std::find(ptr + rect.left(), ptr + rect.right(), 0u));
76 // The space after the painted rectangle should be intact.
77 EXPECT_EQ((ptrdiff_t)kWidth - rect.right(),
78 std::count(ptr + rect.right(), ptr + kWidth, 0u));
80 ptr += kRgbStride / kBytesPerPixel;
84 void RunTest(const webrtc::DesktopSize dest_size,
85 const webrtc::DesktopRect& rect) {
86 ASSERT_TRUE(
87 DoesRectContain(webrtc::DesktopRect::MakeSize(dest_size), rect));
89 // Reset buffers.
90 ResetYuvBuffer();
91 ResetRgbBuffer();
92 FillRgbBuffer(rect);
94 // RGB -> YUV
95 libyuv::ARGBToI420(rgb_buffer_.get(),
96 kRgbStride,
97 yplane_,
98 kYStride,
99 uplane_,
100 kUvStride,
101 vplane_,
102 kUvStride,
103 kWidth,
104 kHeight);
106 // Reset RGB buffer and do opposite conversion.
107 ResetRgbBuffer();
108 ConvertAndScaleYUVToRGB32Rect(yplane_,
109 uplane_,
110 vplane_,
111 kYStride,
112 kUvStride,
113 webrtc::DesktopSize(kWidth, kHeight),
114 webrtc::DesktopRect::MakeWH(kWidth, kHeight),
115 rgb_buffer_.get(),
116 kRgbStride,
117 dest_size,
118 webrtc::DesktopRect::MakeSize(dest_size),
119 rect);
121 // Check if it worked out.
122 CheckRgbBuffer(rect);
125 void TestBasicConversion() {
126 // Whole buffer.
127 RunTest(webrtc::DesktopSize(kWidth, kHeight),
128 webrtc::DesktopRect::MakeWH(kWidth, kHeight));
131 private:
132 size_t yuv_buffer_size_;
133 scoped_ptr<uint8[]> yuv_buffer_;
134 uint8* yplane_;
135 uint8* uplane_;
136 uint8* vplane_;
138 size_t rgb_buffer_size_;
139 scoped_ptr<uint8[]> rgb_buffer_;
141 DISALLOW_COPY_AND_ASSIGN(YuvToRgbTester);
144 TEST(YuvToRgbTest, BasicConversion) {
145 YuvToRgbTester tester;
146 tester.TestBasicConversion();
149 TEST(YuvToRgbTest, Clipping) {
150 YuvToRgbTester tester;
152 webrtc::DesktopSize dest_size = webrtc::DesktopSize(kWidth, kHeight);
153 webrtc::DesktopRect rect =
154 webrtc::DesktopRect::MakeLTRB(0, 0, kWidth - 1, kHeight - 1);
155 // TODO(fbarchard): Allow top/left clipping to odd boundary.
156 for (int i = 0; i < 16; ++i) {
157 webrtc::DesktopRect dest_rect = webrtc::DesktopRect::MakeLTRB(
158 rect.left() + ((i & 1) ? 2 : 0),
159 rect.top() + ((i & 2) ? 2 : 0),
160 rect.right() - ((i & 4) ? 1 : 0),
161 rect.bottom() - ((i & 8) ? 1 : 0));
163 tester.RunTest(dest_size, dest_rect);
167 TEST(YuvToRgbTest, ClippingAndScaling) {
168 YuvToRgbTester tester;
170 webrtc::DesktopSize dest_size =
171 webrtc::DesktopSize(kWidth - 10, kHeight - 10);
172 webrtc::DesktopRect rect =
173 webrtc::DesktopRect::MakeLTRB(6, 6, kWidth - 11, kHeight - 11);
174 for (int i = 0; i < 16; ++i) {
175 webrtc::DesktopRect dest_rect = webrtc::DesktopRect::MakeLTRB(
176 rect.left() + ((i & 1) ? 2 : 0),
177 rect.top() + ((i & 2) ? 2 : 0),
178 rect.right() - ((i & 4) ? 1 : 0),
179 rect.bottom() - ((i & 8) ? 1 : 0));
181 tester.RunTest(dest_size, dest_rect);
185 TEST(ReplaceLfByCrLfTest, Basic) {
186 EXPECT_EQ("ab", ReplaceLfByCrLf("ab"));
187 EXPECT_EQ("\r\nab", ReplaceLfByCrLf("\nab"));
188 EXPECT_EQ("\r\nab\r\n", ReplaceLfByCrLf("\nab\n"));
189 EXPECT_EQ("\r\nab\r\ncd", ReplaceLfByCrLf("\nab\ncd"));
190 EXPECT_EQ("\r\nab\r\ncd\r\n", ReplaceLfByCrLf("\nab\ncd\n"));
191 EXPECT_EQ("\r\n\r\nab\r\n\r\ncd\r\n\r\n",
192 ReplaceLfByCrLf("\n\nab\n\ncd\n\n"));
195 TEST(ReplaceLfByCrLfTest, Speed) {
196 int kLineSize = 128;
197 std::string line(kLineSize, 'a');
198 line[kLineSize - 1] = '\n';
199 // Make a 10M string.
200 int kLineNum = 10 * 1024 * 1024 / kLineSize;
201 std::string buffer;
202 buffer.resize(kLineNum * kLineSize);
203 for (int i = 0; i < kLineNum; ++i) {
204 memcpy(&buffer[i * kLineSize], &line[0], kLineSize);
206 // Convert the string.
207 buffer = ReplaceLfByCrLf(buffer);
208 // Check the converted string.
209 EXPECT_EQ(static_cast<size_t>((kLineSize + 1) * kLineNum), buffer.size());
210 const char* p = &buffer[0];
211 for (int i = 0; i < kLineNum; ++i) {
212 EXPECT_EQ(0, memcmp(&line[0], p, kLineSize - 1));
213 p += kLineSize - 1;
214 EXPECT_EQ('\r', *p++);
215 EXPECT_EQ('\n', *p++);
219 TEST(ReplaceCrLfByLfTest, Basic) {
220 EXPECT_EQ("ab", ReplaceCrLfByLf("ab"));
221 EXPECT_EQ("\nab", ReplaceCrLfByLf("\r\nab"));
222 EXPECT_EQ("\nab\n", ReplaceCrLfByLf("\r\nab\r\n"));
223 EXPECT_EQ("\nab\ncd", ReplaceCrLfByLf("\r\nab\r\ncd"));
224 EXPECT_EQ("\nab\ncd\n", ReplaceCrLfByLf("\r\nab\r\ncd\n"));
225 EXPECT_EQ("\n\nab\n\ncd\n\n",
226 ReplaceCrLfByLf("\r\n\r\nab\r\n\r\ncd\r\n\r\n"));
227 EXPECT_EQ("\rab\rcd\r", ReplaceCrLfByLf("\rab\rcd\r"));
230 TEST(ReplaceCrLfByLfTest, Speed) {
231 int kLineSize = 128;
232 std::string line(kLineSize, 'a');
233 line[kLineSize - 2] = '\r';
234 line[kLineSize - 1] = '\n';
235 // Make a 10M string.
236 int kLineNum = 10 * 1024 * 1024 / kLineSize;
237 std::string buffer;
238 buffer.resize(kLineNum * kLineSize);
239 for (int i = 0; i < kLineNum; ++i) {
240 memcpy(&buffer[i * kLineSize], &line[0], kLineSize);
242 // Convert the string.
243 buffer = ReplaceCrLfByLf(buffer);
244 // Check the converted string.
245 EXPECT_EQ(static_cast<size_t>((kLineSize - 1) * kLineNum), buffer.size());
246 const char* p = &buffer[0];
247 for (int i = 0; i < kLineNum; ++i) {
248 EXPECT_EQ(0, memcmp(&line[0], p, kLineSize - 2));
249 p += kLineSize - 2;
250 EXPECT_EQ('\n', *p++);
254 TEST(StringIsUtf8Test, Basic) {
255 EXPECT_TRUE(StringIsUtf8("", 0));
256 EXPECT_TRUE(StringIsUtf8("\0", 1));
257 EXPECT_TRUE(StringIsUtf8("abc", 3));
258 EXPECT_TRUE(StringIsUtf8("\xc0\x80", 2));
259 EXPECT_TRUE(StringIsUtf8("\xe0\x80\x80", 3));
260 EXPECT_TRUE(StringIsUtf8("\xf0\x80\x80\x80", 4));
261 EXPECT_TRUE(StringIsUtf8("\xf8\x80\x80\x80\x80", 5));
262 EXPECT_TRUE(StringIsUtf8("\xfc\x80\x80\x80\x80\x80", 6));
264 // Not enough continuation characters
265 EXPECT_FALSE(StringIsUtf8("\xc0", 1));
266 EXPECT_FALSE(StringIsUtf8("\xe0\x80", 2));
267 EXPECT_FALSE(StringIsUtf8("\xf0\x80\x80", 3));
268 EXPECT_FALSE(StringIsUtf8("\xf8\x80\x80\x80", 4));
269 EXPECT_FALSE(StringIsUtf8("\xfc\x80\x80\x80\x80", 5));
271 // One more continuation character than needed
272 EXPECT_FALSE(StringIsUtf8("\xc0\x80\x80", 3));
273 EXPECT_FALSE(StringIsUtf8("\xe0\x80\x80\x80", 4));
274 EXPECT_FALSE(StringIsUtf8("\xf0\x80\x80\x80\x80", 5));
275 EXPECT_FALSE(StringIsUtf8("\xf8\x80\x80\x80\x80\x80", 6));
276 EXPECT_FALSE(StringIsUtf8("\xfc\x80\x80\x80\x80\x80\x80", 7));
278 // Invalid first byte
279 EXPECT_FALSE(StringIsUtf8("\xfe\x80\x80\x80\x80\x80\x80", 7));
280 EXPECT_FALSE(StringIsUtf8("\xff\x80\x80\x80\x80\x80\x80", 7));
282 // Invalid continuation byte
283 EXPECT_FALSE(StringIsUtf8("\xc0\x00", 2));
284 EXPECT_FALSE(StringIsUtf8("\xc0\x40", 2));
285 EXPECT_FALSE(StringIsUtf8("\xc0\xc0", 2));
288 } // namespace remoting