summaryrefslogtreecommitdiffstats
path: root/remoting/host/differ.h
blob: 2ad48b9da4d7b07c5af334640bfeb122dce0995d (plain)
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_