// Copyright 2019 The PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <memory>

#include "core/fxcrt/fx_safe_types.h"
#include "core/fxge/cfx_cliprgn.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "core/fxge/dib/fx_dib.h"
#include "testing/fuzzers/pdfium_fuzzer_util.h"
#include "third_party/base/stl_util.h"

namespace {

// Some unused formats were removed, and their slots have been filled in
// `FXDIB_Format::kInvalid` to keep the fuzzer input stable.
constexpr FXDIB_Format kFormat[] = {
    FXDIB_Format::kInvalid,
    FXDIB_Format::k1bppRgb,
    FXDIB_Format::k8bppRgb,
    FXDIB_Format::kRgb,
    FXDIB_Format::kRgb32,
    FXDIB_Format::k1bppMask,
    FXDIB_Format::k8bppMask,
    FXDIB_Format::kInvalid /* Was FXDIB_Format::k8bppRgba */,
    FXDIB_Format::kInvalid /* Was FXDIB_Format::kRgba */,
    FXDIB_Format::kArgb,
    FXDIB_Format::kInvalid /* Was FXDIB_Format::k1bppCmyk */,
    FXDIB_Format::kInvalid /* Was FXDIB_Format::k8bppCmyk */,
    FXDIB_Format::kInvalid /* Was FXDIB_Format::kCmyk */,
    FXDIB_Format::kInvalid /* Was FXDIB_Format::k8bppCmyka */,
    FXDIB_Format::kInvalid /* Was FXDIB_Format::kCmyka */};

}  // namespace

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  constexpr size_t kParameterSize = 33;
  if (size < kParameterSize)
    return 0;

  int width = GetInteger(data);
  int height = GetInteger(data + 4);
  uint32_t argb = GetInteger(data + 8);
  int src_left = GetInteger(data + 12);
  int src_top = GetInteger(data + 16);
  int dest_left = GetInteger(data + 20);
  int dest_top = GetInteger(data + 24);

  BlendMode blend_mode = static_cast<BlendMode>(
      data[28] % (static_cast<int>(BlendMode::kLast) + 1));
  FXDIB_Format dest_format = kFormat[data[29] % pdfium::size(kFormat)];
  FXDIB_Format src_format = kFormat[data[30] % pdfium::size(kFormat)];
  bool is_clip = !(data[31] % 2);
  bool is_rgb_byte_order = !(data[32] % 2);
  size -= kParameterSize;
  data += kParameterSize;

  static constexpr uint32_t kMemLimit = 512000000;  // 512 MB
  static constexpr uint32_t kComponents = 4;
  FX_SAFE_UINT32 mem = width;
  mem *= height;
  mem *= kComponents;
  if (!mem.IsValid() || mem.ValueOrDie() > kMemLimit)
    return 0;

  auto src_bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
  auto dest_bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
  if (!src_bitmap->Create(width, height, src_format) ||
      !dest_bitmap->Create(width, height, dest_format)) {
    return 0;
  }
  if (!src_bitmap->GetBuffer() || !dest_bitmap->GetBuffer()) {
    return 0;
  }

  std::unique_ptr<CFX_ClipRgn> clip_rgn;
  if (is_clip)
    clip_rgn = std::make_unique<CFX_ClipRgn>(width, height);
  if (src_bitmap->IsMaskFormat()) {
    dest_bitmap->CompositeMask(dest_left, dest_top, width, height, src_bitmap,
                               argb, src_left, src_top, blend_mode,
                               clip_rgn.get(), is_rgb_byte_order);
  } else {
    dest_bitmap->CompositeBitmap(dest_left, dest_top, width, height, src_bitmap,
                                 src_left, src_top, blend_mode, clip_rgn.get(),
                                 is_rgb_byte_order);
  }
  return 0;
}
