// Copyright 2016 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

#include "core/fpdfapi/page/cpdf_transferfuncdib.h"

#include <utility>

#include "build/build_config.h"
#include "core/fpdfapi/page/cpdf_transferfunc.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/zip.h"
#include "core/fxge/calculate_pitch.h"

namespace {

CFX_DIBBase::kPlatformRGBStruct MakePlatformRGBStruct(uint8_t red,
                                                      uint8_t green,
                                                      uint8_t blue) {
  // Note that the return value may have an alpha value that will be set to 0.
  return {
      .blue = blue,
      .green = green,
      .red = red,
  };
}

}  // namespace

CPDF_TransferFuncDIB::CPDF_TransferFuncDIB(
    RetainPtr<const CFX_DIBBase> src,
    RetainPtr<CPDF_TransferFunc> transfer_func)
    : src_(std::move(src)),
      transfer_func_(std::move(transfer_func)),
      r_samples_(transfer_func_->GetSamplesR()),
      g_samples_(transfer_func_->GetSamplesG()),
      b_samples_(transfer_func_->GetSamplesB()) {
  SetWidth(src_->GetWidth());
  SetHeight(src_->GetHeight());
  SetFormat(GetDestFormat());
  SetPitch(fxge::CalculatePitch32OrDie(GetBPP(), GetWidth()));
  scanline_.resize(GetPitch());
  CHECK(!HasPalette());
}

CPDF_TransferFuncDIB::~CPDF_TransferFuncDIB() = default;

FXDIB_Format CPDF_TransferFuncDIB::GetDestFormat() const {
  if (src_->IsMaskFormat()) {
    return FXDIB_Format::k8bppMask;
  }

  if (src_->IsAlphaFormat()) {
    return FXDIB_Format::kArgb;
  }

  return CFX_DIBBase::kPlatformRGBFormat;
}

void CPDF_TransferFuncDIB::TranslateScanline(
    pdfium::span<const uint8_t> src_span) const {
  auto scanline_span = pdfium::make_span(scanline_);
  switch (src_->GetFormat()) {
    case FXDIB_Format::kInvalid: {
      break;
    }
    case FXDIB_Format::k1bppRgb: {
      const auto color0 =
          MakePlatformRGBStruct(r_samples_[0], g_samples_[0], b_samples_[0]);
      const auto color1 = MakePlatformRGBStruct(
          r_samples_[255], g_samples_[255], b_samples_[255]);
      auto dest = fxcrt::reinterpret_span<kPlatformRGBStruct>(scanline_span);
      for (int i = 0; i < GetWidth(); i++) {
        const bool is_on = (src_span[i / 8] & (1 << (7 - i % 8)));
        dest[i] = is_on ? color1 : color0;
      }
      break;
    }
    case FXDIB_Format::k1bppMask: {
      const int m0 = r_samples_[0];
      const int m1 = r_samples_[255];
      for (int i = 0; i < GetWidth(); i++) {
        const bool is_on = (src_span[i / 8] & (1 << (7 - i % 8)));
        scanline_[i] = is_on ? m1 : m0;
      }
      break;
    }
    case FXDIB_Format::k8bppRgb: {
      pdfium::span<const uint32_t> src_palette = src_->GetPaletteSpan();
      auto dest = fxcrt::reinterpret_span<kPlatformRGBStruct>(scanline_span);
      auto zip = fxcrt::Zip(src_span.first(GetWidth()), dest);
      if (src_->HasPalette()) {
        for (auto [input, output] : zip) {
          const FX_ARGB src_argb = src_palette[input];
          output = MakePlatformRGBStruct(r_samples_[FXARGB_B(src_argb)],
                                         g_samples_[FXARGB_G(src_argb)],
                                         b_samples_[FXARGB_R(src_argb)]);
        }
      } else {
        for (auto [input, output] : zip) {
          output = MakePlatformRGBStruct(r_samples_[input], g_samples_[input],
                                         b_samples_[input]);
        }
      }
      break;
    }
    case FXDIB_Format::k8bppMask: {
      for (auto [input, output] :
           fxcrt::Zip(src_span.first(GetWidth()), scanline_span)) {
        output = r_samples_[input];
      }
      break;
    }
    case FXDIB_Format::kRgb: {
      auto src =
          fxcrt::reinterpret_span<const FX_BGR_STRUCT<uint8_t>>(src_span);
      auto dest = fxcrt::reinterpret_span<kPlatformRGBStruct>(scanline_span);
      for (auto [input, output] : fxcrt::Zip(src.first(GetWidth()), dest)) {
        output = MakePlatformRGBStruct(r_samples_[input.red],
                                       g_samples_[input.green],
                                       b_samples_[input.blue]);
      }
      break;
    }
    case FXDIB_Format::kRgb32: {
      auto src =
          fxcrt::reinterpret_span<const FX_BGRA_STRUCT<uint8_t>>(src_span);
      auto dest = fxcrt::reinterpret_span<kPlatformRGBStruct>(scanline_span);
      for (auto [input, output] : fxcrt::Zip(src.first(GetWidth()), dest)) {
        output = MakePlatformRGBStruct(r_samples_[input.red],
                                       g_samples_[input.green],
                                       b_samples_[input.blue]);
      }
      break;
    }
    case FXDIB_Format::kArgb: {
      auto src =
          fxcrt::reinterpret_span<const FX_BGRA_STRUCT<uint8_t>>(src_span);
      auto dest =
          fxcrt::reinterpret_span<FX_BGRA_STRUCT<uint8_t>>(scanline_span);
      for (auto [input, output] : fxcrt::Zip(src.first(GetWidth()), dest)) {
        output = {
            .blue = b_samples_[input.blue],
            .green = g_samples_[input.green],
            .red = r_samples_[input.red],
            .alpha = input.alpha,
        };
      }
      break;
    }
  }
}

pdfium::span<const uint8_t> CPDF_TransferFuncDIB::GetScanline(int line) const {
  TranslateScanline(src_->GetScanline(line));
  return scanline_;
}
