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

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

#include <set>

#include "core/fpdfapi/page/cpdf_colorspace.h"
#include "core/fpdfapi/page/cpdf_docpagedata.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/cpdf_object.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fpdfapi/parser/cpdf_string.h"
#include "core/fxcrt/check_op.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/span.h"

CPDF_IndexedCS::CPDF_IndexedCS() : CPDF_BasedCS(Family::kIndexed) {}

CPDF_IndexedCS::~CPDF_IndexedCS() = default;

const CPDF_IndexedCS* CPDF_IndexedCS::AsIndexedCS() const {
  return this;
}

uint32_t CPDF_IndexedCS::v_Load(CPDF_Document* doc,
                                const CPDF_Array* pArray,
                                std::set<const CPDF_Object*>* pVisited) {
  if (pArray->size() < 4) {
    return 0;
  }

  RetainPtr<const CPDF_Object> pBaseObj = pArray->GetDirectObjectAt(1);
  if (HasSameArray(pBaseObj.Get())) {
    return 0;
  }

  auto* pDocPageData = CPDF_DocPageData::FromDocument(doc);
  base_cs_ =
      pDocPageData->GetColorSpaceGuarded(pBaseObj.Get(), nullptr, pVisited);
  if (!base_cs_) {
    return 0;
  }

  // The base color space cannot be a Pattern or Indexed space, according to ISO
  // 32000-1:2008 section 8.6.6.3.
  Family family = base_cs_->GetFamily();
  if (family == Family::kIndexed || family == Family::kPattern) {
    return 0;
  }

  uint32_t base_component_count = base_cs_->ComponentCount();
  DCHECK(base_component_count);
  component_min_max_ = DataVector<IndexedColorMinMax>(base_component_count);
  float defvalue;
  for (uint32_t i = 0; i < component_min_max_.size(); i++) {
    IndexedColorMinMax& comp = component_min_max_[i];
    base_cs_->GetDefaultValue(i, &defvalue, &comp.min, &comp.max);
    comp.max -= comp.min;
  }

  // ISO 32000-1:2008 section 8.6.6.3 says the maximum value is 255.  Clamp
  // the value to this range, so that images with an out-of-range hival value
  // can still be loaded.
  max_index_ = std::clamp(pArray->GetIntegerAt(2), 0, 255);

  RetainPtr<const CPDF_Object> pTableObj = pArray->GetDirectObjectAt(3);
  if (!pTableObj) {
    return 0;
  }

  if (const CPDF_String* str_obj = pTableObj->AsString()) {
    ByteString str_data = str_obj->GetString();
    pdfium::span<const uint8_t> str_span = str_data.unsigned_span();
    lookup_table_ = DataVector<uint8_t>(str_span.begin(), str_span.end());
  } else if (const CPDF_Stream* stream_obj = pTableObj->AsStream()) {
    auto acc =
        pdfium::MakeRetain<CPDF_StreamAcc>(pdfium::WrapRetain(stream_obj));
    acc->LoadAllDataFiltered();
    pdfium::span<const uint8_t> str_span = acc->GetSpan();
    lookup_table_ = DataVector<uint8_t>(str_span.begin(), str_span.end());
  }
  return 1;
}

std::optional<FX_RGB_STRUCT<float>> CPDF_IndexedCS::GetRGB(
    pdfium::span<const float> pBuf) const {
  int32_t index = static_cast<int32_t>(pBuf[0]);
  if (index < 0 || index > max_index_) {
    return std::nullopt;
  }

  DCHECK(!component_min_max_.empty());
  DCHECK_EQ(component_min_max_.size(), base_cs_->ComponentCount());

  FX_SAFE_SIZE_T length = index;
  length += 1;
  length *= component_min_max_.size();
  if (!length.IsValid() || length.ValueOrDie() > lookup_table_.size()) {
    return std::nullopt;
  }

  DataVector<float> comps(component_min_max_.size());
  for (uint32_t i = 0; i < component_min_max_.size(); ++i) {
    const IndexedColorMinMax& comp = component_min_max_[i];
    comps[i] =
        comp.min +
        comp.max * lookup_table_[index * component_min_max_.size() + i] / 255;
  }
  return base_cs_->GetRGB(comps);
}
