// Copyright 2017 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.

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

#ifndef CORE_FXGE_DIB_CSTRETCHENGINE_H_
#define CORE_FXGE_DIB_CSTRETCHENGINE_H_

#include <vector>

#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_memory_wrappers.h"
#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/unowned_ptr.h"
#include "core/fxge/dib/fx_dib.h"
#include "third_party/base/check_op.h"
#include "third_party/base/span.h"

class CFX_DIBBase;
class PauseIndicatorIface;
class ScanlineComposerIface;

class CStretchEngine {
 public:
  static constexpr uint32_t kFixedPointBits = 16;
  static constexpr uint32_t kFixedPointOne = 1 << kFixedPointBits;

  static inline uint32_t FixedFromDouble(double d) {
    return static_cast<uint32_t>(FXSYS_round(d * kFixedPointOne));
  }

  static inline uint32_t FixedFromFloat(float f) {
    return static_cast<uint32_t>(FXSYS_roundf(f * kFixedPointOne));
  }

  static inline uint8_t PixelFromFixed(uint32_t fixed) {
    return static_cast<uint8_t>(fixed >> kFixedPointBits);
  }

  struct PixelWeight {
    static size_t TotalBytesForWeightCount(size_t weight_count);

    void SetStartEnd(int src_start, int src_end, size_t weight_count) {
      CHECK_LT(src_end - src_start, static_cast<int>(weight_count));
      m_SrcStart = src_start;
      m_SrcEnd = src_end;
    }

    uint32_t GetWeightForPosition(int position) const {
      CHECK_GE(position, m_SrcStart);
      CHECK_LE(position, m_SrcEnd);
      return m_Weights[position - m_SrcStart];
    }

    void SetWeightForPosition(int position, uint32_t weight) {
      CHECK_GE(position, m_SrcStart);
      CHECK_LE(position, m_SrcEnd);
      m_Weights[position - m_SrcStart] = weight;
    }

    // NOTE: relies on defined behaviour for unsigned overflow to
    // decrement the previous position, as needed.
    void RemoveLastWeightAndAdjust(uint32_t weight_change) {
      CHECK_GT(m_SrcEnd, m_SrcStart);
      --m_SrcEnd;
      m_Weights[m_SrcEnd - m_SrcStart] += weight_change;
    }

    int m_SrcStart;
    int m_SrcEnd;           // Note: inclusive, [0, -1] for empty range at 0.
    uint32_t m_Weights[1];  // Not really 1, variable size.
  };

  class WeightTable {
   public:
    WeightTable();
    ~WeightTable();

    // Accepts a negative `dest_len` argument, producing a "mirror
    // image" of the result if `dest_len` is negative.
    bool CalculateWeights(int dest_len,
                          int dest_min,
                          int dest_max,
                          int src_len,
                          int src_min,
                          int src_max,
                          const FXDIB_ResampleOptions& options);

    const PixelWeight* GetPixelWeight(int pixel) const;
    PixelWeight* GetPixelWeight(int pixel) {
      return const_cast<PixelWeight*>(
          static_cast<const WeightTable*>(this)->GetPixelWeight(pixel));
    }

   private:
    int m_DestMin = 0;
    size_t m_ItemSizeBytes = 0;
    size_t m_WeightTablesSizeBytes = 0;
    std::vector<uint8_t, FxAllocAllocator<uint8_t>> m_WeightTables;
  };

  CStretchEngine(ScanlineComposerIface* pDestBitmap,
                 FXDIB_Format dest_format,
                 int dest_width,
                 int dest_height,
                 const FX_RECT& clip_rect,
                 const RetainPtr<const CFX_DIBBase>& pSrcBitmap,
                 const FXDIB_ResampleOptions& options);
  ~CStretchEngine();

  bool Continue(PauseIndicatorIface* pPause);
  bool StartStretchHorz();
  bool ContinueStretchHorz(PauseIndicatorIface* pPause);
  void StretchVert();

  const FXDIB_ResampleOptions& GetResampleOptionsForTest() const {
    return m_ResampleOptions;
  }

 private:
  enum class State : uint8_t { kInitial, kHorizontal, kVertical };

  enum class TransformMethod : uint8_t {
    k1BppTo8Bpp,
    k1BppToManyBpp,
    k8BppTo8Bpp,
    k8BppTo8BppWithAlpha,
    k8BppToManyBpp,
    k8BppToManyBppWithAlpha,
    kManyBpptoManyBpp,
    kManyBpptoManyBppWithAlpha
  };

  const FXDIB_Format m_DestFormat;
  const int m_DestBpp;
  const int m_SrcBpp;
  const bool m_bHasAlpha;
  RetainPtr<const CFX_DIBBase> const m_pSource;
  pdfium::span<const uint32_t> m_pSrcPalette;
  const int m_SrcWidth;
  const int m_SrcHeight;
  UnownedPtr<ScanlineComposerIface> const m_pDestBitmap;
  const int m_DestWidth;
  const int m_DestHeight;
  const FX_RECT m_DestClip;
  std::vector<uint8_t, FxAllocAllocator<uint8_t>> m_DestScanline;
  std::vector<uint8_t, FxAllocAllocator<uint8_t>> m_DestMaskScanline;
  std::vector<uint8_t, FxAllocAllocator<uint8_t>> m_InterBuf;
  std::vector<uint8_t, FxAllocAllocator<uint8_t>> m_ExtraAlphaBuf;
  FX_RECT m_SrcClip;
  int m_InterPitch;
  int m_ExtraMaskPitch;
  FXDIB_ResampleOptions m_ResampleOptions;
  TransformMethod m_TransMethod;
  State m_State = State::kInitial;
  int m_CurRow;
  WeightTable m_WeightTable;
};

#endif  // CORE_FXGE_DIB_CSTRETCHENGINE_H_
