// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "skia/public/mojom/bitmap_skbitmap_mojom_traits.h"

#include "base/ranges/algorithm.h"
#include "third_party/skia/include/core/SkPixelRef.h"

namespace mojo {
namespace {

// Maximum reasonable width and height. We don't try to deserialize bitmaps
// bigger than these dimensions.
// These limits are fairly large to accommodate images from the largest possible
// canvas.
constexpr int kMaxWidth = 64 * 1024;
constexpr int kMaxHeight = 64 * 1024;

// A custom SkPixelRef subclass to wrap a BigBuffer storing the pixel data.
class BigBufferPixelRef final : public SkPixelRef {
 public:
  BigBufferPixelRef(mojo_base::BigBuffer buffer,
                    int width,
                    int height,
                    int row_bytes)
      : SkPixelRef(width, height, buffer.data(), row_bytes),
        buffer_(std::move(buffer)) {}
  ~BigBufferPixelRef() override = default;

 private:
  mojo_base::BigBuffer buffer_;
};

bool CreateSkBitmapForPixelData(SkBitmap* b,
                                const SkImageInfo& image_info,
                                base::span<const uint8_t> pixel_data) {
  // Ensure width and height are reasonable.
  if (image_info.width() > kMaxWidth || image_info.height() > kMaxHeight)
    return false;

  // We require incoming bitmaps to be tightly packed by specifying the
  // rowBytes() as minRowBytes(). Then we compare the number of bytes against
  // `pixel_data.size()` later to verify the actual data is tightly packed.
  if (!b->tryAllocPixels(image_info, image_info.minRowBytes()))
    return false;

  // If the image is empty, return success after setting the image info.
  if (image_info.width() == 0 || image_info.height() == 0)
    return true;

  // If these don't match then the number of bytes sent does not match what the
  // rest of the mojom said there should be.
  if (pixel_data.size() != b->computeByteSize())
    return false;

  // Implementation note: This copy is important from a security perspective as
  // it provides the recipient of the SkBitmap with a stable copy of the data.
  // The sender could otherwise continue modifying the shared memory buffer
  // underlying the BigBuffer instance.
  base::ranges::copy(pixel_data, static_cast<uint8_t*>(b->getPixels()));
  b->notifyPixelsChanged();
  return true;
}

}  // namespace

// static
mojo_base::BigBufferView StructTraits<skia::mojom::BitmapN32DataView,
                                      SkBitmap>::pixel_data(const SkBitmap& b) {
  CHECK_EQ(b.rowBytes(), b.info().minRowBytes());
  return mojo_base::BigBufferView(base::make_span(
      static_cast<uint8_t*>(b.getPixels()), b.computeByteSize()));
}

// static
bool StructTraits<skia::mojom::BitmapN32DataView, SkBitmap>::Read(
    skia::mojom::BitmapN32DataView data,
    SkBitmap* b) {
  SkImageInfo image_info;
  if (!data.ReadImageInfo(&image_info))
    return false;

  mojo_base::BigBufferView pixel_data_view;
  if (!data.ReadPixelData(&pixel_data_view))
    return false;

  return CreateSkBitmapForPixelData(b, std::move(image_info),
                                    pixel_data_view.data());
}

// static
mojo_base::BigBufferView
StructTraits<skia::mojom::BitmapWithArbitraryBppDataView, SkBitmap>::pixel_data(
    const SkBitmap& b) {
  CHECK_EQ(b.rowBytes(), b.info().minRowBytes());
  return mojo_base::BigBufferView(base::make_span(
      static_cast<uint8_t*>(b.getPixels()), b.computeByteSize()));
}

// static
bool StructTraits<skia::mojom::BitmapWithArbitraryBppDataView, SkBitmap>::Read(
    skia::mojom::BitmapWithArbitraryBppDataView data,
    SkBitmap* b) {
  SkImageInfo image_info;
  if (!data.ReadImageInfo(&image_info))
    return false;

  mojo_base::BigBufferView pixel_data_view;
  if (!data.ReadPixelData(&pixel_data_view))
    return false;

  return CreateSkBitmapForPixelData(b, std::move(image_info),
                                    pixel_data_view.data());
}

// static
mojo_base::BigBufferView
StructTraits<skia::mojom::BitmapMappedFromTrustedProcessDataView,
             SkBitmap>::pixel_data(const SkBitmap& b) {
  CHECK_EQ(b.rowBytes(), b.info().minRowBytes());
  return mojo_base::BigBufferView(base::make_span(
      static_cast<uint8_t*>(b.getPixels()), b.computeByteSize()));
}

// static
bool StructTraits<
    skia::mojom::BitmapMappedFromTrustedProcessDataView,
    SkBitmap>::Read(skia::mojom::BitmapMappedFromTrustedProcessDataView data,
                    SkBitmap* b) {
  SkImageInfo image_info;
  if (!data.ReadImageInfo(&image_info))
    return false;

  // Ensure width and height are reasonable.
  if (image_info.width() > kMaxWidth || image_info.height() > kMaxHeight)
    return false;

  // If the image is empty, return success after setting the image info.
  if (image_info.width() == 0 || image_info.height() == 0)
    return b->tryAllocPixels(image_info);

  // Otherwise, set a custom PixelRef to retain the BigBuffer. This avoids
  // making another copy of the pixel data.

  mojo_base::BigBufferView pixel_data_view;
  if (!data.ReadPixelData(&pixel_data_view))
    return false;

  // We require incoming bitmaps to be tightly packed by specifying the
  // rowBytes() as minRowBytes(). Then we compare the number of bytes against
  // `pixel_data_view.data().size()` later to verify the actual data is tightly
  // packed.
  if (!b->setInfo(image_info, image_info.minRowBytes()))
    return false;

  // If these don't match then the number of bytes sent does not match what the
  // rest of the mojom said there should be.
  if (b->computeByteSize() != pixel_data_view.data().size())
    return false;

  // Allow the resultant SkBitmap to refer to the given BigBuffer. Note, the
  // sender could continue modifying the pixels of the buffer, which could be a
  // security concern for some applications. The trade-off is performance.
  b->setPixelRef(
      sk_make_sp<BigBufferPixelRef>(
          mojo_base::BigBufferView::ToBigBuffer(std::move(pixel_data_view)),
          image_info.width(), image_info.height(), image_info.minRowBytes()),
      0, 0);
  return true;
}

// static
base::span<const uint8_t>
StructTraits<skia::mojom::InlineBitmapDataView, SkBitmap>::pixel_data(
    const SkBitmap& b) {
  CHECK_EQ(b.rowBytes(), b.info().minRowBytes());
  return base::make_span(static_cast<uint8_t*>(b.getPixels()),
                         b.computeByteSize());
}

// static
bool StructTraits<skia::mojom::InlineBitmapDataView, SkBitmap>::Read(
    skia::mojom::InlineBitmapDataView data,
    SkBitmap* b) {
  SkImageInfo image_info;
  if (!data.ReadImageInfo(&image_info))
    return false;

  mojo::ArrayDataView<uint8_t> pixel_data_view;
  data.GetPixelDataDataView(&pixel_data_view);

  base::span<const uint8_t> pixel_data_bytes(pixel_data_view.data(),
                                             pixel_data_view.size());

  return CreateSkBitmapForPixelData(b, std::move(image_info),
                                    std::move(pixel_data_bytes));
}

}  // namespace mojo
