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

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#ifndef CORE_FXGE_DIB_CFX_DIBBASE_H_
#define CORE_FXGE_DIB_CFX_DIBBASE_H_

#include <stddef.h>
#include <stdint.h>

#include "build/build_config.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/span.h"
#include "core/fxcrt/span_util.h"
#include "core/fxge/dib/fx_dib.h"

#if defined(PDF_USE_SKIA)
#include "third_party/skia/include/core/SkRefCnt.h"  // nogncheck
#endif

class CFX_ClipRgn;
class CFX_DIBitmap;
class CFX_Matrix;
class PauseIndicatorIface;
struct FX_RECT;

#if defined(PDF_USE_SKIA)
class SkImage;
#endif  // defined(PDF_USE_SKIA)

// Base class for all Device-Independent Bitmaps.
class CFX_DIBBase : public Retainable {
 public:
#if BUILDFLAG(IS_APPLE)
  // Matches Apple's kCGBitmapByteOrder32Little in fx_quartz_device.cpp.
  static constexpr FXDIB_Format kPlatformRGBFormat = FXDIB_Format::kRgb32;
  using kPlatformRGBStruct = FX_BGRA_STRUCT<uint8_t>;
#else   // BUILDFLAG(IS_APPLE)
  static constexpr FXDIB_Format kPlatformRGBFormat = FXDIB_Format::kRgb;
  using kPlatformRGBStruct = FX_BGR_STRUCT<uint8_t>;
#endif  // BUILDFLAG(IS_APPLE)

  static constexpr uint32_t kPaletteSize = 256;

  virtual pdfium::span<const uint8_t> GetScanline(int line) const = 0;
  virtual bool SkipToScanline(int line, PauseIndicatorIface* pPause) const;
  virtual size_t GetEstimatedImageMemoryBurden() const;
#if BUILDFLAG(IS_WIN) || defined(PDF_USE_SKIA)
  // Calls Realize() if needed. Otherwise, return `this`.
  virtual RetainPtr<const CFX_DIBitmap> RealizeIfNeeded() const;
#endif

  template <typename T>
  pdfium::span<const T> GetScanlineAs(int line) const {
    return fxcrt::reinterpret_span<const T>(GetScanline(line));
  }

  int GetWidth() const { return width_; }
  int GetHeight() const { return height_; }
  uint32_t GetPitch() const { return pitch_; }

  FXDIB_Format GetFormat() const { return format_; }
  int GetBPP() const { return GetBppFromFormat(GetFormat()); }
  bool IsMaskFormat() const { return GetIsMaskFromFormat(GetFormat()); }
  bool IsAlphaFormat() const { return GetIsAlphaFromFormat(GetFormat()); }
  bool IsOpaqueImage() const { return !IsMaskFormat() && !IsAlphaFormat(); }

  bool HasPalette() const { return !palette_.empty(); }
  pdfium::span<const uint32_t> GetPaletteSpan() const { return palette_; }
  size_t GetRequiredPaletteSize() const;
  uint32_t GetPaletteArgb(int index) const;
  void SetPaletteArgb(int index, uint32_t color);

  // Copies into internally-owned palette.
  void SetPalette(pdfium::span<const uint32_t> src_palette);

  // Moves palette into internally-owned palette.
  void TakePalette(DataVector<uint32_t> src_palette);

  RetainPtr<CFX_DIBitmap> Realize() const;
  RetainPtr<CFX_DIBitmap> ClipTo(const FX_RECT& rect) const;
  // `format` must be different from the existing format.
  // Only supports `FXDIB_Format::kRgb` and `FXDIB_Format::k8bppRgb`.
  RetainPtr<CFX_DIBitmap> ConvertTo(FXDIB_Format format) const;
  RetainPtr<CFX_DIBitmap> StretchTo(int dest_width,
                                    int dest_height,
                                    const FXDIB_ResampleOptions& options,
                                    const FX_RECT* pClip) const;
  RetainPtr<CFX_DIBitmap> TransformTo(const CFX_Matrix& mtDest,
                                      int* left,
                                      int* top) const;
  RetainPtr<CFX_DIBitmap> SwapXY(bool bXFlip, bool bYFlip) const;
  RetainPtr<CFX_DIBitmap> FlipImage(bool bXFlip, bool bYFlip) const;

  RetainPtr<CFX_DIBitmap> CloneAlphaMask() const;

  bool GetOverlapRect(int& dest_left,
                      int& dest_top,
                      int& width,
                      int& height,
                      int src_width,
                      int src_height,
                      int& src_left,
                      int& src_top,
                      const CFX_ClipRgn* pClipRgn) const;

  // Whether alpha is premultiplied (if `IsAlphaFormat()`).
  virtual bool IsPremultiplied() const;

#if defined(PDF_USE_SKIA)
  // Realizes an `SkImage` from this DIB.
  //
  // This may share the underlying pixels, in which case, this DIB should not be
  // modified during the lifetime of the `SkImage`.
  virtual sk_sp<SkImage> RealizeSkImage() const;
#endif  // defined(PDF_USE_SKIA)

 protected:
  CFX_DIBBase();
  ~CFX_DIBBase() override;

  // Returns the color palette, or an empty vector if there is no palette.
  static DataVector<uint32_t> ConvertBuffer(
      FXDIB_Format dest_format,
      pdfium::span<uint8_t> dest_buf,
      int dest_pitch,
      int width,
      int height,
      const RetainPtr<const CFX_DIBBase>& pSrcBitmap,
      int src_left,
      int src_top);

  RetainPtr<CFX_DIBitmap> ClipToInternal(const FX_RECT* pClip) const;
  void BuildPalette();
  int FindPalette(uint32_t color) const;

  void SetFormat(FXDIB_Format format) { format_ = format; }
  void SetWidth(int width) { width_ = width; }
  void SetHeight(int height) { height_ = height; }
  void SetPitch(uint32_t pitch) { pitch_ = pitch; }

  DataVector<uint32_t> palette_;

 private:
  FXDIB_Format format_ = FXDIB_Format::kInvalid;
  int width_ = 0;
  int height_ = 0;
  uint32_t pitch_ = 0;
};

#endif  // CORE_FXGE_DIB_CFX_DIBBASE_H_
