/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/modules/desktop_capture/differ.h"

#include "string.h"

#include "webrtc/modules/desktop_capture/differ_block.h"
#include "webrtc/system_wrappers/interface/logging.h"

namespace webrtc {

Differ::Differ(int width, int height, int bpp, int stride) {
  // Dimensions of screen.
  width_ = width;
  height_ = height;
  bytes_per_pixel_ = bpp;
  bytes_per_row_ = stride;

  // Calc number of blocks (full and partial) required to cover entire image.
  // One additional row/column is added as a boundary on the right & bottom.
  diff_info_width_ = ((width_ + kBlockSize - 1) / kBlockSize) + 1;
  diff_info_height_ = ((height_ + kBlockSize - 1) / kBlockSize) + 1;
  diff_info_size_ = diff_info_width_ * diff_info_height_ * sizeof(bool);
  diff_info_.reset(new bool[diff_info_size_]);
}

Differ::~Differ() {}

void Differ::CalcDirtyRegion(const uint8_t* prev_buffer,
                             const uint8_t* curr_buffer,
                             DesktopRegion* region) {
  // Identify all the blocks that contain changed pixels.
  MarkDirtyBlocks(prev_buffer, curr_buffer);

  // Now that we've identified the blocks that have changed, merge adjacent
  // blocks to minimize the number of rects that we return.
  MergeBlocks(region);
}

void Differ::MarkDirtyBlocks(const uint8_t* prev_buffer,
                             const uint8_t* curr_buffer) {
  memset(diff_info_.get(), 0, diff_info_size_);

  // Calc number of full blocks.
  int x_full_blocks = width_ / kBlockSize;
  int y_full_blocks = height_ / kBlockSize;

  // Calc size of partial blocks which may be present on right and bottom edge.
  int partial_column_width = width_ - (x_full_blocks * kBlockSize);
  int partial_row_height = height_ - (y_full_blocks * kBlockSize);

  // Offset from the start of one block-column to the next.
  int block_x_offset = bytes_per_pixel_ * kBlockSize;
  // Offset from the start of one block-row to the next.
  int block_y_stride = (width_ * bytes_per_pixel_) * kBlockSize;
  // Offset from the start of one diff_info row to the next.
  int diff_info_stride = diff_info_width_ * sizeof(bool);

  const uint8_t* prev_block_row_start = prev_buffer;
  const uint8_t* curr_block_row_start = curr_buffer;
  bool* diff_info_row_start = diff_info_.get();

  for (int y = 0; y < y_full_blocks; y++) {
    const uint8_t* prev_block = prev_block_row_start;
    const uint8_t* curr_block = curr_block_row_start;
    bool* diff_info = diff_info_row_start;

    for (int x = 0; x < x_full_blocks; x++) {
      // Mark this block as being modified so that it gets incorporated into
      // a dirty rect.
      *diff_info = BlockDifference(prev_block, curr_block, bytes_per_row_);
      prev_block += block_x_offset;
      curr_block += block_x_offset;
      diff_info += sizeof(bool);
    }

    // If there is a partial column at the end, handle it.
    // This condition should rarely, if ever, occur.
    if (partial_column_width != 0) {
      *diff_info = !PartialBlocksEqual(prev_block, curr_block, bytes_per_row_,
                                       partial_column_width, kBlockSize);
      diff_info += sizeof(bool);
    }

    // Update pointers for next row.
    prev_block_row_start += block_y_stride;
    curr_block_row_start += block_y_stride;
    diff_info_row_start += diff_info_stride;
  }

  // If the screen height is not a multiple of the block size, then this
  // handles the last partial row. This situation is far more common than the
  // 'partial column' case.
  if (partial_row_height != 0) {
    const uint8_t* prev_block = prev_block_row_start;
    const uint8_t* curr_block = curr_block_row_start;
    bool* diff_info = diff_info_row_start;
    for (int x = 0; x < x_full_blocks; x++) {
      *diff_info = !PartialBlocksEqual(prev_block, curr_block,
                                       bytes_per_row_,
                                       kBlockSize, partial_row_height);
      prev_block += block_x_offset;
      curr_block += block_x_offset;
      diff_info += sizeof(bool);
    }
    if (partial_column_width != 0) {
      *diff_info = !PartialBlocksEqual(prev_block, curr_block, bytes_per_row_,
                                       partial_column_width,
                                       partial_row_height);
      diff_info += sizeof(bool);
    }
  }
}

bool Differ::PartialBlocksEqual(const uint8_t* prev_buffer,
                                const uint8_t* curr_buffer,
                                int stride, int width, int height) {
  int width_bytes = width * bytes_per_pixel_;
  for (int y = 0; y < height; y++) {
    if (memcmp(prev_buffer, curr_buffer, width_bytes) != 0)
      return false;
    prev_buffer += bytes_per_row_;
    curr_buffer += bytes_per_row_;
  }
  return true;
}

void Differ::MergeBlocks(DesktopRegion* region) {
  region->Clear();

  bool* diff_info_row_start = diff_info_.get();
  int diff_info_stride = diff_info_width_ * sizeof(bool);

  for (int y = 0; y < diff_info_height_; y++) {
    bool* diff_info = diff_info_row_start;
    for (int x = 0; x < diff_info_width_; x++) {
      if (*diff_info) {
        // We've found a modified block. Look at blocks to the right and below
        // to group this block with as many others as we can.
        int left = x * kBlockSize;
        int top = y * kBlockSize;
        int width = 1;
        int height = 1;
        *diff_info = false;

        // Group with blocks to the right.
        // We can keep looking until we find an unchanged block because we
        // have a boundary block which is never marked as having diffs.
        bool* right = diff_info + 1;
        while (*right) {
          *right++ = false;
          width++;
        }

        // Group with blocks below.
        // The entire width of blocks that we matched above much match for
        // each row that we add.
        bool* bottom = diff_info;
        bool found_new_row;
        do {
          found_new_row = true;
          bottom += diff_info_stride;
          right = bottom;
          for (int x2 = 0; x2 < width; x2++) {
            if (!*right++) {
              found_new_row = false;
            }
          }

          if (found_new_row) {
            height++;

            // We need to go back and erase the diff markers so that we don't
            // try to add these blocks a second time.
            right = bottom;
            for (int x2 = 0; x2 < width; x2++) {
              *right++ = false;
            }
          }
        } while (found_new_row);

        // Add rect to list of dirty rects.
        width *= kBlockSize;
        if (left + width > width_) {
          width = width_ - left;
        }
        height *= kBlockSize;
        if (top + height > height_) {
          height = height_ - top;
        }
        region->AddRect(DesktopRect::MakeXYWH(left, top, width, height));
      }

      // Increment to next block in this row.
      diff_info++;
    }

    // Go to start of next row.
    diff_info_row_start += diff_info_stride;
  }
}

}  // namespace webrtc
