1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
// Copyright (c) 2010 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.
#ifndef REMOTING_HOST_DIFFER_H_
#define REMOTING_HOST_DIFFER_H_
#include <vector>
#include "base/basictypes.h"
#include "base/scoped_ptr.h"
#include "gfx/rect.h"
namespace remoting {
typedef std::vector<gfx::Rect> DirtyRects;
typedef uint8 DiffInfo;
// Size (in pixels) of each square block used for diffing.
// This must be a multiple of sizeof(uint64).
static const int kBlockSize = 32;
class Differ {
public:
// Create a differ that operates on bitmaps with the specified width, height
// and bytes_per_pixel.
Differ(int width, int height, int bytes_per_pixel);
// Given the previous and current screen buffer, calculate the set of
// rectangles that enclose all the changed pixels in the new screen.
void CalcDirtyRects(const void* prev_buffer, const void* curr_buffer,
DirtyRects* rects);
// Identify all of the blocks that contain changed pixels.
void MarkDirtyBlocks(const void* prev_buffer, const void* curr_buffer);
// Diff a small block of image and return non-zero if there is a diff.
// Currently, this just returns 0 or 1, but this may change in the future
// to return the number of pixels changed.
DiffInfo DiffBlock(const uint8* prev_buffer, const uint8* curr_buffer,
int stride);
// Diff a small block of image and return non-zero if there is a diff.
// This checks only the part of the block specified by the width and
// height parameters.
// This is much slower than DiffBlock() since it cannot assume that the
// full block is being checked.
// If we force the capturer to always return images whose width/height are
// multiples of kBlockSize, then this will never be called.
DiffInfo DiffPartialBlock(const uint8* prev_buffer, const uint8* curr_buffer,
int stride, int width, int height);
// After the dirty blocks have been identified, this routine merges adjacent
// blocks into larger rectangular units.
// The goal is to minimize the number of rects that cover the dirty blocks,
// although it is not required to calc the absolute minimum of rects.
void MergeBlocks(DirtyRects* rects);
// Allow tests to access our private parts.
friend class DifferTest;
private:
// Dimensions of screen.
int width_;
int height_;
// Number of bytes for each pixel in source and dest bitmap.
int bytes_per_pixel_;
// Number of bytes in each row of the image.
int bytes_per_row_;
// Diff information for each block in the image.
scoped_array<DiffInfo> diff_info_;
// Dimensions and total size of diff info array.
int diff_info_width_;
int diff_info_height_;
int diff_info_size_;
DISALLOW_COPY_AND_ASSIGN(Differ);
};
} // namespace remoting
#endif // REMOTING_HOST_DIFFER_H_
|