// 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_imageobject.h"

#include <utility>

#include "core/fpdfapi/page/cpdf_docpagedata.h"
#include "core/fpdfapi/page/cpdf_image.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxge/dib/cfx_dibbase.h"
#include "core/fxge/dib/cfx_dibitmap.h"

CPDF_ImageObject::CPDF_ImageObject(int32_t content_stream)
    : CPDF_PageObject(content_stream) {}

CPDF_ImageObject::CPDF_ImageObject() : CPDF_ImageObject(kNoContentStream) {}

CPDF_ImageObject::~CPDF_ImageObject() {
  MaybePurgeCache();
}

CPDF_PageObject::Type CPDF_ImageObject::GetType() const {
  return Type::kImage;
}

void CPDF_ImageObject::Transform(const CFX_Matrix& matrix) {
  matrix_.Concat(matrix);
  CalcBoundingBox();
  SetDirty(true);
}

bool CPDF_ImageObject::IsImage() const {
  return true;
}

CPDF_ImageObject* CPDF_ImageObject::AsImage() {
  return this;
}

const CPDF_ImageObject* CPDF_ImageObject::AsImage() const {
  return this;
}

void CPDF_ImageObject::CalcBoundingBox() {
  static constexpr CFX_FloatRect kRect(0.0f, 0.0f, 1.0f, 1.0f);
  SetOriginalRect(kRect);
  SetRect(matrix_.TransformRect(kRect));
}

void CPDF_ImageObject::SetImage(RetainPtr<CPDF_Image> pImage) {
  MaybePurgeCache();
  image_ = std::move(pImage);
}

RetainPtr<CPDF_Image> CPDF_ImageObject::GetImage() const {
  return image_;
}

RetainPtr<CFX_DIBitmap> CPDF_ImageObject::GetIndependentBitmap() const {
  RetainPtr<CFX_DIBBase> pSource = GetImage()->LoadDIBBase();

  // Realize() is non-virtual, and can't be overloaded by CPDF_DIB to
  // return a full-up CPDF_DIB subclass. Instead, it only works upon the
  // CFX_DIBBase, which is convenient since none of its members point to
  // objects owned by |this| or the form containing |this|. As a result,
  // the new bitmap may outlive them, giving the "independent" property
  // this method is named after.
  return pSource ? pSource->Realize() : nullptr;
}

void CPDF_ImageObject::SetInitialImageMatrix(const CFX_Matrix& matrix) {
  InitializeOriginalMatrix(matrix);
  SetImageMatrix(matrix);
}

void CPDF_ImageObject::SetImageMatrix(const CFX_Matrix& matrix) {
  matrix_ = matrix;
  CalcBoundingBox();
}

void CPDF_ImageObject::MaybePurgeCache() {
  if (!image_ || image_->IsGoingToBeDestroyed()) {
    return;
  }

  RetainPtr<const CPDF_Stream> pStream = image_->GetStream();
  if (!pStream) {
    return;
  }

  uint32_t objnum = pStream->GetObjNum();
  if (!objnum) {
    return;
  }

  auto* pDoc = image_->GetDocument();
  CHECK(pDoc);

  image_.Reset();  // Clear my reference before asking the cache.
  pDoc->MaybePurgeImage(objnum);
}
