// 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);
}

CPDF_ImageObject* CPDF_ImageObject::AsImage() {
  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* doc = image_->GetDocument();
  CHECK(doc);

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