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 "remoting/base/util.h"
9 #include "base/logging.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/time/time.h"
12 #include "third_party/libyuv/include/libyuv/convert.h"
13 #include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
17 enum { kBytesPerPixelRGB32
= 4 };
19 static int CalculateRGBOffset(int x
, int y
, int stride
) {
20 return stride
* y
+ kBytesPerPixelRGB32
* x
;
23 // Do not write LOG messages in this routine since it is called from within
24 // our LOG message handler. Bad things will happen.
25 std::string
GetTimestampString() {
26 base::Time t
= base::Time::NowFromSystemTime();
27 base::Time::Exploded tex
;
29 return base::StringPrintf("%02d%02d/%02d%02d%02d:",
30 tex
.month
, tex
.day_of_month
,
31 tex
.hour
, tex
.minute
, tex
.second
);
34 int RoundToTwosMultiple(int x
) {
38 webrtc::DesktopRect
AlignRect(const webrtc::DesktopRect
& rect
) {
39 int x
= RoundToTwosMultiple(rect
.left());
40 int y
= RoundToTwosMultiple(rect
.top());
41 int right
= RoundToTwosMultiple(rect
.right() + 1);
42 int bottom
= RoundToTwosMultiple(rect
.bottom() + 1);
43 return webrtc::DesktopRect::MakeLTRB(x
, y
, right
, bottom
);
46 void CopyRGB32Rect(const uint8_t* source_buffer
,
48 const webrtc::DesktopRect
& source_buffer_rect
,
51 const webrtc::DesktopRect
& dest_buffer_rect
,
52 const webrtc::DesktopRect
& dest_rect
) {
53 DCHECK(DoesRectContain(dest_buffer_rect
, dest_rect
));
54 DCHECK(DoesRectContain(source_buffer_rect
, dest_rect
));
56 // Get the address of the starting point.
57 source_buffer
+= CalculateRGBOffset(
58 dest_rect
.left() - source_buffer_rect
.left(),
59 dest_rect
.top() - source_buffer_rect
.top(),
61 dest_buffer
+= CalculateRGBOffset(
62 dest_rect
.left() - dest_buffer_rect
.left(),
63 dest_rect
.top() - dest_buffer_rect
.top(),
66 // Copy pixels in the rectangle line by line.
67 const int bytes_per_line
= kBytesPerPixelRGB32
* dest_rect
.width();
68 for (int i
= 0 ; i
< dest_rect
.height(); ++i
) {
69 memcpy(dest_buffer
, source_buffer
, bytes_per_line
);
70 source_buffer
+= source_stride
;
71 dest_buffer
+= dest_stride
;
75 std::string
ReplaceLfByCrLf(const std::string
& in
) {
77 out
.resize(2 * in
.size());
78 char* out_p_begin
= &out
[0];
79 char* out_p
= out_p_begin
;
80 const char* in_p_begin
= &in
[0];
81 const char* in_p_end
= &in
[in
.size()];
82 for (const char* in_p
= in_p_begin
; in_p
< in_p_end
; ++in_p
) {
89 out
.resize(out_p
- out_p_begin
);
93 std::string
ReplaceCrLfByLf(const std::string
& in
) {
95 out
.resize(in
.size());
96 char* out_p_begin
= &out
[0];
97 char* out_p
= out_p_begin
;
98 const char* in_p_begin
= &in
[0];
99 const char* in_p_end
= &in
[in
.size()];
100 for (const char* in_p
= in_p_begin
; in_p
< in_p_end
; ++in_p
) {
102 if ((c
== '\r') && (in_p
+ 1 < in_p_end
) && (*(in_p
+ 1) == '\n')) {
109 out
.resize(out_p
- out_p_begin
);
113 bool StringIsUtf8(const char* data
, size_t length
) {
114 const char* ptr
= data
;
115 const char* ptr_end
= data
+ length
;
116 while (ptr
!= ptr_end
) {
117 if ((*ptr
& 0x80) == 0) {
118 // Single-byte symbol.
120 } else if ((*ptr
& 0xc0) == 0x80 || (*ptr
& 0xfe) == 0xfe) {
121 // Invalid first byte.
124 // First byte of a multi-byte symbol. The bits from 2 to 6 are the count
125 // of continuation bytes (up to 5 of them).
126 for (char first
= *ptr
<< 1; first
& 0x80; first
<<= 1) {
129 // Missing continuation byte.
133 // Invalid continuation byte.
134 if ((*ptr
& 0xc0) != 0x80)
145 bool DoesRectContain(const webrtc::DesktopRect
& a
,
146 const webrtc::DesktopRect
& b
) {
147 webrtc::DesktopRect
intersection(a
);
148 intersection
.IntersectWith(b
);
149 return intersection
.equals(b
);
152 } // namespace remoting