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

#include "public/fpdf_edit.h"

#include "core/fpdfapi/cpdf_modulemgr.h"
#include "core/fpdfapi/page/cpdf_image.h"
#include "core/fpdfapi/page/cpdf_imageobject.h"
#include "core/fpdfapi/page/cpdf_page.h"
#include "core/fpdfapi/page/cpdf_pageobject.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_name.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fpdfapi/render/cpdf_dibsource.h"
#include "fpdfsdk/cpdfsdk_customaccess.h"
#include "fpdfsdk/cpdfsdk_helpers.h"
#include "third_party/base/ptr_util.h"

namespace {

// These checks ensure the consistency of colorspace values across core/ and
// public/.
static_assert(PDFCS_DEVICEGRAY == FPDF_COLORSPACE_DEVICEGRAY,
              "PDFCS_DEVICEGRAY value mismatch");
static_assert(PDFCS_DEVICERGB == FPDF_COLORSPACE_DEVICERGB,
              "PDFCS_DEVICERGB value mismatch");
static_assert(PDFCS_DEVICECMYK == FPDF_COLORSPACE_DEVICECMYK,
              "PDFCS_DEVICECMYK value mismatch");
static_assert(PDFCS_CALGRAY == FPDF_COLORSPACE_CALGRAY,
              "PDFCS_CALGRAY value mismatch");
static_assert(PDFCS_CALRGB == FPDF_COLORSPACE_CALRGB,
              "PDFCS_CALRGB value mismatch");
static_assert(PDFCS_LAB == FPDF_COLORSPACE_LAB, "PDFCS_LAB value mismatch");
static_assert(PDFCS_ICCBASED == FPDF_COLORSPACE_ICCBASED,
              "PDFCS_ICCBASED value mismatch");
static_assert(PDFCS_SEPARATION == FPDF_COLORSPACE_SEPARATION,
              "PDFCS_SEPARATION value mismatch");
static_assert(PDFCS_DEVICEN == FPDF_COLORSPACE_DEVICEN,
              "PDFCS_DEVICEN value mismatch");
static_assert(PDFCS_INDEXED == FPDF_COLORSPACE_INDEXED,
              "PDFCS_INDEXED value mismatch");
static_assert(PDFCS_PATTERN == FPDF_COLORSPACE_PATTERN,
              "PDFCS_PATTERN value mismatch");

RetainPtr<IFX_SeekableReadStream> MakeSeekableReadStream(
    FPDF_FILEACCESS* pFileAccess) {
  return pdfium::MakeRetain<CPDFSDK_CustomAccess>(pFileAccess);
}

bool LoadJpegHelper(FPDF_PAGE* pages,
                    int nCount,
                    FPDF_PAGEOBJECT image_object,
                    FPDF_FILEACCESS* fileAccess,
                    bool inlineJpeg) {
  if (!image_object || !fileAccess)
    return false;

  CPDF_ImageObject* pImgObj =
      CPDFPageObjectFromFPDFPageObject(image_object)->AsImage();
  if (!pImgObj)
    return false;

  if (pages) {
    for (int index = 0; index < nCount; index++) {
      CPDF_Page* pPage = CPDFPageFromFPDFPage(pages[index]);
      if (pPage)
        pImgObj->GetImage()->ResetCache(pPage, nullptr);
    }
  }

  RetainPtr<IFX_SeekableReadStream> pFile = MakeSeekableReadStream(fileAccess);
  if (inlineJpeg)
    pImgObj->GetImage()->SetJpegImageInline(pFile);
  else
    pImgObj->GetImage()->SetJpegImage(pFile);
  pImgObj->SetDirty(true);
  return true;
}

}  // namespace

FPDF_EXPORT FPDF_PAGEOBJECT FPDF_CALLCONV
FPDFPageObj_NewImageObj(FPDF_DOCUMENT document) {
  CPDF_Document* pDoc = CPDFDocumentFromFPDFDocument(document);
  if (!pDoc)
    return nullptr;

  auto pImageObj = pdfium::MakeUnique<CPDF_ImageObject>();
  pImageObj->SetImage(pdfium::MakeRetain<CPDF_Image>(pDoc));

  // Caller takes ownership.
  return FPDFPageObjectFromCPDFPageObject(pImageObj.release());
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFImageObj_LoadJpegFile(FPDF_PAGE* pages,
                          int nCount,
                          FPDF_PAGEOBJECT image_object,
                          FPDF_FILEACCESS* fileAccess) {
  return LoadJpegHelper(pages, nCount, image_object, fileAccess, false);
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFImageObj_LoadJpegFileInline(FPDF_PAGE* pages,
                                int nCount,
                                FPDF_PAGEOBJECT image_object,
                                FPDF_FILEACCESS* fileAccess) {
  return LoadJpegHelper(pages, nCount, image_object, fileAccess, true);
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFImageObj_SetMatrix(FPDF_PAGEOBJECT image_object,
                       double a,
                       double b,
                       double c,
                       double d,
                       double e,
                       double f) {
  if (!image_object)
    return false;

  CPDF_ImageObject* pImgObj =
      CPDFPageObjectFromFPDFPageObject(image_object)->AsImage();
  if (!pImgObj)
    return false;

  pImgObj->set_matrix(CFX_Matrix(static_cast<float>(a), static_cast<float>(b),
                                 static_cast<float>(c), static_cast<float>(d),
                                 static_cast<float>(e), static_cast<float>(f)));
  pImgObj->CalcBoundingBox();
  pImgObj->SetDirty(true);
  return true;
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFImageObj_SetBitmap(FPDF_PAGE* pages,
                       int nCount,
                       FPDF_PAGEOBJECT image_object,
                       FPDF_BITMAP bitmap) {
  if (!image_object || !bitmap || !pages)
    return false;

  CPDF_ImageObject* pImgObj =
      CPDFPageObjectFromFPDFPageObject(image_object)->AsImage();
  if (!pImgObj)
    return false;

  for (int index = 0; index < nCount; index++) {
    CPDF_Page* pPage = CPDFPageFromFPDFPage(pages[index]);
    if (pPage)
      pImgObj->GetImage()->ResetCache(pPage, nullptr);
  }
  RetainPtr<CFX_DIBitmap> holder(CFXDIBitmapFromFPDFBitmap(bitmap));
  pImgObj->GetImage()->SetImage(holder);
  pImgObj->CalcBoundingBox();
  pImgObj->SetDirty(true);
  return true;
}

FPDF_EXPORT FPDF_BITMAP FPDF_CALLCONV
FPDFImageObj_GetBitmap(FPDF_PAGEOBJECT image_object) {
  CPDF_PageObject* pObj = CPDFPageObjectFromFPDFPageObject(image_object);
  if (!pObj || !pObj->IsImage())
    return nullptr;

  RetainPtr<CPDF_Image> pImg = pObj->AsImage()->GetImage();
  if (!pImg)
    return nullptr;

  RetainPtr<CFX_DIBSource> pSource = pImg->LoadDIBSource();
  if (!pSource)
    return nullptr;

  RetainPtr<CFX_DIBitmap> pBitmap;
  // If the source image has a representation of 1 bit per pixel, then convert
  // it to a grayscale bitmap having 1 byte per pixel, since bitmaps have no
  // concept of bits. Otherwise, convert the source image to a bitmap directly,
  // retaining its color representation.
  if (pSource->GetBPP() == 1)
    pBitmap = pSource->CloneConvert(FXDIB_8bppRgb);
  else
    pBitmap = pSource->Clone(nullptr);

  return FPDFBitmapFromCFXDIBitmap(pBitmap.Leak());
}

FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFImageObj_GetImageDataDecoded(FPDF_PAGEOBJECT image_object,
                                 void* buffer,
                                 unsigned long buflen) {
  CPDF_PageObject* pObj = CPDFPageObjectFromFPDFPageObject(image_object);
  if (!pObj || !pObj->IsImage())
    return 0;

  RetainPtr<CPDF_Image> pImg = pObj->AsImage()->GetImage();
  if (!pImg)
    return 0;

  CPDF_Stream* pImgStream = pImg->GetStream();
  if (!pImgStream)
    return 0;

  return DecodeStreamMaybeCopyAndReturnLength(pImgStream, buffer, buflen);
}

FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFImageObj_GetImageDataRaw(FPDF_PAGEOBJECT image_object,
                             void* buffer,
                             unsigned long buflen) {
  CPDF_PageObject* pObj = CPDFPageObjectFromFPDFPageObject(image_object);
  if (!pObj || !pObj->IsImage())
    return 0;

  RetainPtr<CPDF_Image> pImg = pObj->AsImage()->GetImage();
  if (!pImg)
    return 0;

  CPDF_Stream* pImgStream = pImg->GetStream();
  if (!pImgStream)
    return 0;

  auto streamAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pImgStream);
  streamAcc->LoadAllDataRaw();

  const uint32_t len = streamAcc->GetSize();
  if (!buffer || buflen < len)
    return len;

  memcpy(buffer, streamAcc->GetData(), len);
  return len;
}

FPDF_EXPORT int FPDF_CALLCONV
FPDFImageObj_GetImageFilterCount(FPDF_PAGEOBJECT image_object) {
  CPDF_PageObject* pObj = CPDFPageObjectFromFPDFPageObject(image_object);
  if (!pObj || !pObj->IsImage())
    return 0;

  RetainPtr<CPDF_Image> pImg = pObj->AsImage()->GetImage();
  if (!pImg)
    return 0;

  CPDF_Dictionary* pDict = pImg->GetDict();
  CPDF_Object* pFilter = pDict ? pDict->GetDirectObjectFor("Filter") : nullptr;
  if (!pFilter)
    return 0;

  if (pFilter->IsArray())
    return pFilter->AsArray()->GetCount();
  if (pFilter->IsName())
    return 1;

  return 0;
}

FPDF_EXPORT unsigned long FPDF_CALLCONV
FPDFImageObj_GetImageFilter(FPDF_PAGEOBJECT image_object,
                            int index,
                            void* buffer,
                            unsigned long buflen) {
  if (index < 0 || index >= FPDFImageObj_GetImageFilterCount(image_object))
    return 0;

  CPDF_PageObject* pObj = CPDFPageObjectFromFPDFPageObject(image_object);
  CPDF_Object* pFilter =
      pObj->AsImage()->GetImage()->GetDict()->GetDirectObjectFor("Filter");
  ByteString bsFilter;
  if (pFilter->IsName())
    bsFilter = pFilter->AsName()->GetString();
  else
    bsFilter = pFilter->AsArray()->GetStringAt(index);

  unsigned long len = bsFilter.GetLength() + 1;
  if (buffer && len <= buflen)
    memcpy(buffer, bsFilter.c_str(), len);
  return len;
}

FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV
FPDFImageObj_GetImageMetadata(FPDF_PAGEOBJECT image_object,
                              FPDF_PAGE page,
                              FPDF_IMAGEOBJ_METADATA* metadata) {
  CPDF_PageObject* pObj = CPDFPageObjectFromFPDFPageObject(image_object);
  if (!pObj || !pObj->IsImage() || !metadata)
    return false;

  RetainPtr<CPDF_Image> pImg = pObj->AsImage()->GetImage();
  if (!pImg)
    return false;

  metadata->marked_content_id = pObj->m_ContentMark.GetMarkedContentID();

  const int nPixelWidth = pImg->GetPixelWidth();
  const int nPixelHeight = pImg->GetPixelHeight();
  metadata->width = nPixelWidth;
  metadata->height = nPixelHeight;

  const float nWidth = pObj->m_Right - pObj->m_Left;
  const float nHeight = pObj->m_Top - pObj->m_Bottom;
  constexpr int nPointsPerInch = 72;
  if (nWidth != 0 && nHeight != 0) {
    metadata->horizontal_dpi = nPixelWidth / nWidth * nPointsPerInch;
    metadata->vertical_dpi = nPixelHeight / nHeight * nPointsPerInch;
  }

  metadata->bits_per_pixel = 0;
  metadata->colorspace = FPDF_COLORSPACE_UNKNOWN;

  CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
  if (!pPage || !pPage->GetDocument() || !pImg->GetStream())
    return true;

  auto pSource = pdfium::MakeRetain<CPDF_DIBSource>();
  CPDF_DIBSource::LoadState ret = pSource->StartLoadDIBSource(
      pPage->GetDocument(), pImg->GetStream(), false, nullptr,
      pPage->m_pPageResources.Get());
  if (ret == CPDF_DIBSource::LoadState::kFail)
    return true;

  metadata->bits_per_pixel = pSource->GetBPP();
  if (pSource->GetColorSpace())
    metadata->colorspace = pSource->GetColorSpace()->GetFamily();

  return true;
}
