/*
 *  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 "modules/desktop_capture/desktop_frame.h"

#include <algorithm>
#include <cmath>
#include <cstdint>
#include <cstring>
#include <memory>
#include <utility>

#include "modules/desktop_capture/desktop_capture_types.h"
#include "modules/desktop_capture/desktop_geometry.h"
#include "modules/desktop_capture/shared_memory.h"
#include "rtc_base/checks.h"
#include "third_party/libyuv/include/libyuv/planar_functions.h"

namespace webrtc {

DesktopFrame::DesktopFrame(DesktopSize size,
                           int stride,
                           FourCC pixel_format,
                           uint8_t* data,
                           SharedMemory* shared_memory,
                           FrameTexture* texture)
    : data_(data),
      shared_memory_(shared_memory),
      texture_(texture),
      size_(size),
      stride_(stride),
      pixel_format_(pixel_format),
      capture_time_ms_(0),
      capturer_id_(DesktopCapturerId::kUnknown) {
  RTC_DCHECK(size_.width() >= 0);
  RTC_DCHECK(size_.height() >= 0);
}

DesktopFrame::DesktopFrame(DesktopSize size,
                           int stride,
                           uint8_t* data,
                           SharedMemory* shared_memory)
    : DesktopFrame(size, stride, FOURCC_ARGB, data, shared_memory) {}

DesktopFrame::~DesktopFrame() = default;

void DesktopFrame::CopyPixelsFrom(const uint8_t* src_buffer,
                                  int src_stride,
                                  const DesktopRect& dest_rect) {
  RTC_CHECK(DesktopRect::MakeSize(size()).ContainsRect(dest_rect));

  uint8_t* dest = GetFrameDataAtPos(dest_rect.top_left());
  libyuv::CopyPlane(src_buffer, src_stride, dest, stride(),
                    DesktopFrame::kBytesPerPixel * dest_rect.width(),
                    dest_rect.height());
}

void DesktopFrame::CopyPixelsFrom(const DesktopFrame& src_frame,
                                  const DesktopVector& src_pos,
                                  const DesktopRect& dest_rect) {
  RTC_CHECK(DesktopRect::MakeSize(src_frame.size())
                .ContainsRect(
                    DesktopRect::MakeOriginSize(src_pos, dest_rect.size())));
  RTC_CHECK_EQ(pixel_format(), src_frame.pixel_format());

  CopyPixelsFrom(src_frame.GetFrameDataAtPos(src_pos), src_frame.stride(),
                 dest_rect);
}

bool DesktopFrame::CopyIntersectingPixelsFrom(const DesktopFrame& src_frame,
                                              double horizontal_scale,
                                              double vertical_scale) {
  const DesktopVector& origin = top_left();
  const DesktopVector& src_frame_origin = src_frame.top_left();

  DesktopVector src_frame_offset = src_frame_origin.subtract(origin);

  // Determine the intersection, first adjusting its origin to account for any
  // DPI scaling.
  DesktopRect intersection_rect = src_frame.rect();
  if (horizontal_scale != 1.0 || vertical_scale != 1.0) {
    DesktopVector origin_adjustment(
        static_cast<int>(
            std::round((horizontal_scale - 1.0) * src_frame_offset.x())),
        static_cast<int>(
            std::round((vertical_scale - 1.0) * src_frame_offset.y())));

    intersection_rect.Translate(origin_adjustment);

    src_frame_offset = src_frame_offset.add(origin_adjustment);
  }

  intersection_rect.IntersectWith(rect());
  if (intersection_rect.is_empty()) {
    return false;
  }

  // Translate the intersection rect to be relative to the outer rect.
  intersection_rect.Translate(-origin.x(), -origin.y());

  // Determine source position for the copy (offsets of outer frame from
  // source origin, if positive).
  int32_t src_pos_x = std::max(0, -src_frame_offset.x());
  int32_t src_pos_y = std::max(0, -src_frame_offset.y());

  CopyPixelsFrom(src_frame, DesktopVector(src_pos_x, src_pos_y),
                 intersection_rect);
  return true;
}

DesktopRect DesktopFrame::rect() const {
  const float scale = scale_factor();
  // Only scale the size.
  return DesktopRect::MakeXYWH(top_left().x(), top_left().y(),
                               size().width() / scale, size().height() / scale);
}

float DesktopFrame::scale_factor() const {
  float scale = 1.0f;

#if defined(WEBRTC_MAC) || defined(CHROMEOS)
  // At least on Windows the logical and physical pixel are the same
  // See http://crbug.com/948362.
  if (!dpi().is_zero() && dpi().x() == dpi().y())
    scale = dpi().x() / kStandardDPI;
#endif

  return scale;
}

uint8_t* DesktopFrame::GetFrameDataAtPos(const DesktopVector& pos) const {
  RTC_DCHECK(data());
  return data() + stride() * pos.y() + DesktopFrame::kBytesPerPixel * pos.x();
}

void DesktopFrame::CopyFrameInfoFrom(const DesktopFrame& other) {
  set_dpi(other.dpi());
  set_capture_time_ms(other.capture_time_ms());
  set_capturer_id(other.capturer_id());
  *mutable_updated_region() = other.updated_region();
  set_top_left(other.top_left());
  set_icc_profile(other.icc_profile());
  set_may_contain_cursor(other.may_contain_cursor());
  set_device_scale_factor(other.device_scale_factor());
}

void DesktopFrame::MoveFrameInfoFrom(DesktopFrame* other) {
  set_dpi(other->dpi());
  set_capture_time_ms(other->capture_time_ms());
  set_capturer_id(other->capturer_id());
  mutable_updated_region()->Swap(other->mutable_updated_region());
  set_top_left(other->top_left());
  set_icc_profile(other->icc_profile());
  set_may_contain_cursor(other->may_contain_cursor());
  set_device_scale_factor(other->device_scale_factor());
}

bool DesktopFrame::FrameDataIsBlack() const {
  RTC_DCHECK(data());
  if (size().is_empty())
    return false;

  uint32_t* pixel = reinterpret_cast<uint32_t*>(data());
  for (int i = 0; i < size().width() * size().height(); ++i) {
    if (*pixel++)
      return false;
  }
  return true;
}

void DesktopFrame::SetFrameDataToBlack() {
  RTC_DCHECK(data());
  const uint8_t kBlackPixelValue = 0x00;
  memset(data(), kBlackPixelValue, stride() * size().height());
}

BasicDesktopFrame::BasicDesktopFrame(DesktopSize size)
    : BasicDesktopFrame(size, FOURCC_ARGB) {}

BasicDesktopFrame::BasicDesktopFrame(DesktopSize size, FourCC pixel_format)
    : DesktopFrame(size,
                   kBytesPerPixel * size.width(),
                   pixel_format,
                   new uint8_t[kBytesPerPixel * size.width() * size.height()](),
                   nullptr) {}

BasicDesktopFrame::~BasicDesktopFrame() {
  delete[] data_;
}

// static
DesktopFrame* BasicDesktopFrame::CopyOf(const DesktopFrame& frame) {
  DesktopFrame* result =
      new BasicDesktopFrame(frame.size(), frame.pixel_format());
  // TODO(crbug.com/1330019): Temporary workaround for a known libyuv crash when
  // the height or width is 0. Remove this once this change has been merged.
  if (frame.size().width() && frame.size().height()) {
    libyuv::CopyPlane(frame.data(), frame.stride(), result->data(),
                      result->stride(), frame.size().width() * kBytesPerPixel,
                      frame.size().height());
  }
  result->CopyFrameInfoFrom(frame);
  return result;
}

// static
std::unique_ptr<DesktopFrame> SharedMemoryDesktopFrame::Create(
    DesktopSize size,
    FourCC pixel_format,
    SharedMemoryFactory* shared_memory_factory) {
  RTC_DCHECK(shared_memory_factory);

  size_t buffer_size = size.height() * size.width() * kBytesPerPixel;
  std::unique_ptr<SharedMemory> shared_memory =
      shared_memory_factory->CreateSharedMemory(buffer_size);
  if (!shared_memory)
    return nullptr;

  return std::make_unique<SharedMemoryDesktopFrame>(
      size, size.width() * kBytesPerPixel, pixel_format,
      std::move(shared_memory));
}

SharedMemoryDesktopFrame::SharedMemoryDesktopFrame(
    DesktopSize size,
    int stride,
    std::unique_ptr<SharedMemory> shared_memory)
    : SharedMemoryDesktopFrame(size,
                               stride,
                               FOURCC_ARGB,
                               std::move(shared_memory)) {}

SharedMemoryDesktopFrame::SharedMemoryDesktopFrame(DesktopSize size,
                                                   int stride,
                                                   FourCC pixel_format,
                                                   SharedMemory* shared_memory)
    : DesktopFrame(size,
                   stride,
                   pixel_format,
                   reinterpret_cast<uint8_t*>(shared_memory->data()),
                   shared_memory) {}

SharedMemoryDesktopFrame::SharedMemoryDesktopFrame(
    DesktopSize size,
    int stride,
    FourCC pixel_format,
    std::unique_ptr<SharedMemory> shared_memory)
    : SharedMemoryDesktopFrame(size,
                               stride,
                               pixel_format,
                               shared_memory.release()) {}

SharedMemoryDesktopFrame::~SharedMemoryDesktopFrame() {
  delete shared_memory_;
}

}  // namespace webrtc
