Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / remoting / base / util_unittest.cc
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.
4
5 #include <algorithm>
6
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"
11
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;
19
20 namespace remoting {
21
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);
30
31     rgb_buffer_size_ = kWidth * kHeight * kBytesPerPixel;
32     rgb_buffer_.reset(new uint8[rgb_buffer_size_]);
33
34     ResetYuvBuffer();
35     ResetRgbBuffer();
36   }
37
38   ~YuvToRgbTester() {}
39
40   void ResetYuvBuffer() {
41     memset(yuv_buffer_.get(), 0, yuv_buffer_size_);
42   }
43
44   void ResetRgbBuffer() {
45     memset(rgb_buffer_.get(), 0, rgb_buffer_size_);
46   }
47
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;
56     }
57   }
58
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));
71
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));
75
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));
79       }
80       ptr += kRgbStride / kBytesPerPixel;
81     }
82   }
83
84   void RunTest(const webrtc::DesktopSize dest_size,
85                const webrtc::DesktopRect& rect) {
86     ASSERT_TRUE(
87         DoesRectContain(webrtc::DesktopRect::MakeSize(dest_size), rect));
88
89     // Reset buffers.
90     ResetYuvBuffer();
91     ResetRgbBuffer();
92     FillRgbBuffer(rect);
93
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);
105
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);
120
121     // Check if it worked out.
122     CheckRgbBuffer(rect);
123   }
124
125   void TestBasicConversion() {
126     // Whole buffer.
127     RunTest(webrtc::DesktopSize(kWidth, kHeight),
128             webrtc::DesktopRect::MakeWH(kWidth, kHeight));
129   }
130
131  private:
132   size_t yuv_buffer_size_;
133   scoped_ptr<uint8[]> yuv_buffer_;
134   uint8* yplane_;
135   uint8* uplane_;
136   uint8* vplane_;
137
138   size_t rgb_buffer_size_;
139   scoped_ptr<uint8[]> rgb_buffer_;
140
141   DISALLOW_COPY_AND_ASSIGN(YuvToRgbTester);
142 };
143
144 TEST(YuvToRgbTest, BasicConversion) {
145   YuvToRgbTester tester;
146   tester.TestBasicConversion();
147 }
148
149 TEST(YuvToRgbTest, Clipping) {
150   YuvToRgbTester tester;
151
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));
162
163     tester.RunTest(dest_size, dest_rect);
164   }
165 }
166
167 TEST(YuvToRgbTest, ClippingAndScaling) {
168   YuvToRgbTester tester;
169
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));
180
181     tester.RunTest(dest_size, dest_rect);
182   }
183 }
184
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"));
193 }
194
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);
205   }
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++);
216   }
217 }
218
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"));
228 }
229
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);
241   }
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++);
251   }
252 }
253
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));
263
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));
270
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));
277
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));
281
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));
286 }
287
288 }  // namespace remoting