// Copyright 2016 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 "core/fpdfapi/page/cpdf_image.h"

#include <algorithm>
#include <memory>
#include <utility>
#include <vector>

#include "constants/stream_dict_common.h"
#include "core/fpdfapi/cpdf_modulemgr.h"
#include "core/fpdfapi/page/cpdf_page.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_boolean.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/cpdf_name.h"
#include "core/fpdfapi/parser/cpdf_number.h"
#include "core/fpdfapi/parser/cpdf_reference.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_string.h"
#include "core/fpdfapi/render/cpdf_dibsource.h"
#include "core/fpdfapi/render/cpdf_pagerendercache.h"
#include "core/fxcodec/codec/ccodec_jpegmodule.h"
#include "core/fxcrt/fx_stream.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "core/fxge/fx_dib.h"
#include "third_party/base/numerics/safe_conversions.h"
#include "third_party/base/ptr_util.h"

CPDF_Image::CPDF_Image(CPDF_Document* pDoc) : m_pDocument(pDoc) {}

CPDF_Image::CPDF_Image(CPDF_Document* pDoc,
                       std::unique_ptr<CPDF_Stream> pStream)
    : m_bIsInline(true), m_pDocument(pDoc), m_pStream(std::move(pStream)) {
  ASSERT(m_pStream.IsOwned());
  FinishInitialization(m_pStream->GetDict());
}

CPDF_Image::CPDF_Image(CPDF_Document* pDoc, uint32_t dwStreamObjNum)
    : m_pDocument(pDoc),
      m_pStream(ToStream(pDoc->GetIndirectObject(dwStreamObjNum))) {
  ASSERT(!m_pStream.IsOwned());
  FinishInitialization(m_pStream->GetDict());
}

CPDF_Image::~CPDF_Image() {}

void CPDF_Image::FinishInitialization(CPDF_Dictionary* pStreamDict) {
  m_pOC = pStreamDict->GetDictFor("OC");
  m_bIsMask = !pStreamDict->KeyExist("ColorSpace") ||
              pStreamDict->GetIntegerFor("ImageMask");
  m_bInterpolate = !!pStreamDict->GetIntegerFor("Interpolate");
  m_Height = pStreamDict->GetIntegerFor("Height");
  m_Width = pStreamDict->GetIntegerFor("Width");
}

void CPDF_Image::ConvertStreamToIndirectObject() {
  if (!m_pStream->IsInline())
    return;

  ASSERT(m_pStream.IsOwned());
  m_pDocument->AddIndirectObject(m_pStream.Release());
}

CPDF_Dictionary* CPDF_Image::GetDict() const {
  return m_pStream ? m_pStream->GetDict() : nullptr;
}

std::unique_ptr<CPDF_Dictionary> CPDF_Image::InitJPEG(uint8_t* pData,
                                                      uint32_t size) {
  int32_t width;
  int32_t height;
  int32_t num_comps;
  int32_t bits;
  bool color_trans;
  if (!CPDF_ModuleMgr::Get()->GetJpegModule()->LoadInfo(
          pData, size, &width, &height, &num_comps, &bits, &color_trans)) {
    return nullptr;
  }

  auto pDict =
      pdfium::MakeUnique<CPDF_Dictionary>(m_pDocument->GetByteStringPool());
  pDict->SetNewFor<CPDF_Name>("Type", "XObject");
  pDict->SetNewFor<CPDF_Name>("Subtype", "Image");
  pDict->SetNewFor<CPDF_Number>("Width", width);
  pDict->SetNewFor<CPDF_Number>("Height", height);
  const char* csname = nullptr;
  if (num_comps == 1) {
    csname = "DeviceGray";
  } else if (num_comps == 3) {
    csname = "DeviceRGB";
  } else if (num_comps == 4) {
    csname = "DeviceCMYK";
    CPDF_Array* pDecode = pDict->SetNewFor<CPDF_Array>("Decode");
    for (int n = 0; n < 4; n++) {
      pDecode->AddNew<CPDF_Number>(1);
      pDecode->AddNew<CPDF_Number>(0);
    }
  }
  pDict->SetNewFor<CPDF_Name>("ColorSpace", csname);
  pDict->SetNewFor<CPDF_Number>("BitsPerComponent", bits);
  pDict->SetNewFor<CPDF_Name>("Filter", "DCTDecode");
  if (!color_trans) {
    CPDF_Dictionary* pParms =
        pDict->SetNewFor<CPDF_Dictionary>(pdfium::stream::kDecodeParms);
    pParms->SetNewFor<CPDF_Number>("ColorTransform", 0);
  }
  m_bIsMask = false;
  m_Width = width;
  m_Height = height;
  if (!m_pStream)
    m_pStream = pdfium::MakeUnique<CPDF_Stream>();
  return pDict;
}

void CPDF_Image::SetJpegImage(const RetainPtr<IFX_SeekableReadStream>& pFile) {
  uint32_t size = pdfium::base::checked_cast<uint32_t>(pFile->GetSize());
  if (!size)
    return;

  uint32_t dwEstimateSize = std::min(size, 8192U);
  std::vector<uint8_t> data(dwEstimateSize);
  if (!pFile->ReadBlock(data.data(), 0, dwEstimateSize))
    return;

  std::unique_ptr<CPDF_Dictionary> pDict =
      InitJPEG(data.data(), dwEstimateSize);
  if (!pDict && size > dwEstimateSize) {
    data.resize(size);
    pFile->ReadBlock(data.data(), 0, size);
    pDict = InitJPEG(data.data(), size);
  }
  if (!pDict)
    return;

  m_pStream->InitStreamFromFile(pFile, std::move(pDict));
}

void CPDF_Image::SetJpegImageInline(
    const RetainPtr<IFX_SeekableReadStream>& pFile) {
  uint32_t size = pdfium::base::checked_cast<uint32_t>(pFile->GetSize());
  if (!size)
    return;

  std::vector<uint8_t> data(size);
  if (!pFile->ReadBlock(data.data(), 0, size))
    return;

  std::unique_ptr<CPDF_Dictionary> pDict = InitJPEG(data.data(), size);
  if (!pDict)
    return;

  m_pStream->InitStream(&(data[0]), size, std::move(pDict));
}

void CPDF_Image::SetImage(const RetainPtr<CFX_DIBitmap>& pBitmap) {
  int32_t BitmapWidth = pBitmap->GetWidth();
  int32_t BitmapHeight = pBitmap->GetHeight();
  if (BitmapWidth < 1 || BitmapHeight < 1)
    return;

  auto pDict =
      pdfium::MakeUnique<CPDF_Dictionary>(m_pDocument->GetByteStringPool());
  pDict->SetNewFor<CPDF_Name>("Type", "XObject");
  pDict->SetNewFor<CPDF_Name>("Subtype", "Image");
  pDict->SetNewFor<CPDF_Number>("Width", BitmapWidth);
  pDict->SetNewFor<CPDF_Number>("Height", BitmapHeight);

  const int32_t bpp = pBitmap->GetBPP();
  size_t dest_pitch = 0;
  bool bCopyWithoutAlpha = true;
  if (bpp == 1) {
    int32_t reset_a = 0;
    int32_t reset_r = 0;
    int32_t reset_g = 0;
    int32_t reset_b = 0;
    int32_t set_a = 0;
    int32_t set_r = 0;
    int32_t set_g = 0;
    int32_t set_b = 0;
    if (!pBitmap->IsAlphaMask()) {
      std::tie(reset_a, reset_r, reset_g, reset_b) =
          ArgbDecode(pBitmap->GetPaletteArgb(0));
      std::tie(set_a, set_r, set_g, set_b) =
          ArgbDecode(pBitmap->GetPaletteArgb(1));
    }
    if (set_a == 0 || reset_a == 0) {
      pDict->SetNewFor<CPDF_Boolean>("ImageMask", true);
      if (reset_a == 0) {
        CPDF_Array* pArray = pDict->SetNewFor<CPDF_Array>("Decode");
        pArray->AddNew<CPDF_Number>(1);
        pArray->AddNew<CPDF_Number>(0);
      }
    } else {
      CPDF_Array* pCS = pDict->SetNewFor<CPDF_Array>("ColorSpace");
      pCS->AddNew<CPDF_Name>("Indexed");
      pCS->AddNew<CPDF_Name>("DeviceRGB");
      pCS->AddNew<CPDF_Number>(1);
      ByteString ct;
      {
        // Span's lifetime must end before ReleaseBuffer() below.
        pdfium::span<char> pBuf = ct.GetBuffer(6);
        pBuf[0] = (char)reset_r;
        pBuf[1] = (char)reset_g;
        pBuf[2] = (char)reset_b;
        pBuf[3] = (char)set_r;
        pBuf[4] = (char)set_g;
        pBuf[5] = (char)set_b;
      }
      ct.ReleaseBuffer(6);
      pCS->AddNew<CPDF_String>(ct, true);
    }
    pDict->SetNewFor<CPDF_Number>("BitsPerComponent", 1);
    dest_pitch = (BitmapWidth + 7) / 8;
  } else if (bpp == 8) {
    int32_t iPalette = pBitmap->GetPaletteSize();
    if (iPalette > 0) {
      CPDF_Array* pCS = m_pDocument->NewIndirect<CPDF_Array>();
      pCS->AddNew<CPDF_Name>("Indexed");
      pCS->AddNew<CPDF_Name>("DeviceRGB");
      pCS->AddNew<CPDF_Number>(iPalette - 1);
      std::unique_ptr<uint8_t, FxFreeDeleter> pColorTable(
          FX_Alloc2D(uint8_t, iPalette, 3));
      uint8_t* ptr = pColorTable.get();
      for (int32_t i = 0; i < iPalette; i++) {
        uint32_t argb = pBitmap->GetPaletteArgb(i);
        ptr[0] = (uint8_t)(argb >> 16);
        ptr[1] = (uint8_t)(argb >> 8);
        ptr[2] = (uint8_t)argb;
        ptr += 3;
      }
      auto pNewDict =
          pdfium::MakeUnique<CPDF_Dictionary>(m_pDocument->GetByteStringPool());
      CPDF_Stream* pCTS = m_pDocument->NewIndirect<CPDF_Stream>(
          std::move(pColorTable), iPalette * 3, std::move(pNewDict));
      pCS->AddNew<CPDF_Reference>(m_pDocument.Get(), pCTS->GetObjNum());
      pDict->SetNewFor<CPDF_Reference>("ColorSpace", m_pDocument.Get(),
                                       pCS->GetObjNum());
    } else {
      pDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceGray");
    }
    pDict->SetNewFor<CPDF_Number>("BitsPerComponent", 8);
    dest_pitch = BitmapWidth;
  } else {
    pDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceRGB");
    pDict->SetNewFor<CPDF_Number>("BitsPerComponent", 8);
    dest_pitch = BitmapWidth * 3;
    bCopyWithoutAlpha = false;
  }

  RetainPtr<CFX_DIBitmap> pMaskBitmap;
  if (pBitmap->HasAlpha())
    pMaskBitmap = pBitmap->CloneAlphaMask();

  if (pMaskBitmap) {
    int32_t maskWidth = pMaskBitmap->GetWidth();
    int32_t maskHeight = pMaskBitmap->GetHeight();
    std::unique_ptr<uint8_t, FxFreeDeleter> mask_buf;
    int32_t mask_size = 0;
    auto pMaskDict =
        pdfium::MakeUnique<CPDF_Dictionary>(m_pDocument->GetByteStringPool());
    pMaskDict->SetNewFor<CPDF_Name>("Type", "XObject");
    pMaskDict->SetNewFor<CPDF_Name>("Subtype", "Image");
    pMaskDict->SetNewFor<CPDF_Number>("Width", maskWidth);
    pMaskDict->SetNewFor<CPDF_Number>("Height", maskHeight);
    pMaskDict->SetNewFor<CPDF_Name>("ColorSpace", "DeviceGray");
    pMaskDict->SetNewFor<CPDF_Number>("BitsPerComponent", 8);
    if (pMaskBitmap->GetFormat() != FXDIB_1bppMask) {
      mask_buf.reset(FX_Alloc2D(uint8_t, maskHeight, maskWidth));
      mask_size = maskHeight * maskWidth;  // Safe since checked alloc returned.
      for (int32_t a = 0; a < maskHeight; a++) {
        memcpy(mask_buf.get() + a * maskWidth, pMaskBitmap->GetScanline(a),
               maskWidth);
      }
    }
    pMaskDict->SetNewFor<CPDF_Number>("Length", mask_size);
    CPDF_Stream* pNewStream = m_pDocument->NewIndirect<CPDF_Stream>(
        std::move(mask_buf), mask_size, std::move(pMaskDict));
    pDict->SetNewFor<CPDF_Reference>("SMask", m_pDocument.Get(),
                                     pNewStream->GetObjNum());
  }

  uint8_t* src_buf = pBitmap->GetBuffer();
  int32_t src_pitch = pBitmap->GetPitch();
  uint8_t* dest_buf = FX_Alloc2D(uint8_t, dest_pitch, BitmapHeight);
  // Safe as checked alloc returned.
  size_t dest_size = dest_pitch * BitmapHeight;
  uint8_t* pDest = dest_buf;
  if (bCopyWithoutAlpha) {
    for (int32_t i = 0; i < BitmapHeight; i++) {
      memcpy(pDest, src_buf, dest_pitch);
      pDest += dest_pitch;
      src_buf += src_pitch;
    }
  } else {
    int32_t src_offset = 0;
    int32_t dest_offset = 0;
    for (int32_t row = 0; row < BitmapHeight; row++) {
      src_offset = row * src_pitch;
      for (int32_t column = 0; column < BitmapWidth; column++) {
        float alpha = 1;
        pDest[dest_offset] = (uint8_t)(src_buf[src_offset + 2] * alpha);
        pDest[dest_offset + 1] = (uint8_t)(src_buf[src_offset + 1] * alpha);
        pDest[dest_offset + 2] = (uint8_t)(src_buf[src_offset] * alpha);
        dest_offset += 3;
        src_offset += bpp == 24 ? 3 : 4;
      }

      pDest += dest_pitch;
      dest_offset = 0;
    }
  }
  if (!m_pStream)
    m_pStream = pdfium::MakeUnique<CPDF_Stream>();

  m_pStream->InitStream(dest_buf, dest_size, std::move(pDict));
  m_bIsMask = pBitmap->IsAlphaMask();
  m_Width = BitmapWidth;
  m_Height = BitmapHeight;
  FX_Free(dest_buf);
}

void CPDF_Image::ResetCache(CPDF_Page* pPage,
                            const RetainPtr<CFX_DIBitmap>& pBitmap) {
  RetainPtr<CPDF_Image> pHolder(this);
  pPage->GetRenderCache()->ResetBitmap(pHolder, pBitmap);
}

RetainPtr<CFX_DIBSource> CPDF_Image::LoadDIBSource() const {
  auto source = pdfium::MakeRetain<CPDF_DIBSource>();
  if (!source->Load(m_pDocument.Get(), m_pStream.Get()))
    return nullptr;

  if (!source->IsJBigImage())
    return source;

  CPDF_DIBSource::LoadState ret = CPDF_DIBSource::LoadState::kContinue;
  while (ret == CPDF_DIBSource::LoadState::kContinue)
    ret = source->ContinueLoadDIBSource(nullptr);
  return ret == CPDF_DIBSource::LoadState::kSuccess ? source : nullptr;
}

RetainPtr<CFX_DIBSource> CPDF_Image::DetachBitmap() {
  return std::move(m_pDIBSource);
}

RetainPtr<CFX_DIBSource> CPDF_Image::DetachMask() {
  return std::move(m_pMask);
}

bool CPDF_Image::StartLoadDIBSource(const CPDF_Dictionary* pFormResource,
                                    CPDF_Dictionary* pPageResource,
                                    bool bStdCS,
                                    uint32_t GroupFamily,
                                    bool bLoadMask) {
  auto source = pdfium::MakeRetain<CPDF_DIBSource>();
  CPDF_DIBSource::LoadState ret = source->StartLoadDIBSource(
      m_pDocument.Get(), m_pStream.Get(), true, pFormResource, pPageResource,
      bStdCS, GroupFamily, bLoadMask);
  if (ret == CPDF_DIBSource::LoadState::kFail) {
    m_pDIBSource.Reset();
    return false;
  }
  m_pDIBSource = source;
  if (ret == CPDF_DIBSource::LoadState::kContinue)
    return true;

  m_pMask = source->DetachMask();
  m_MatteColor = source->GetMatteColor();
  return false;
}

bool CPDF_Image::Continue(PauseIndicatorIface* pPause) {
  RetainPtr<CPDF_DIBSource> pSource = m_pDIBSource.As<CPDF_DIBSource>();
  CPDF_DIBSource::LoadState ret = pSource->ContinueLoadDIBSource(pPause);
  if (ret == CPDF_DIBSource::LoadState::kContinue)
    return true;

  if (ret == CPDF_DIBSource::LoadState::kSuccess) {
    m_pMask = pSource->DetachMask();
    m_MatteColor = pSource->GetMatteColor();
  } else {
    m_pDIBSource.Reset();
  }
  return false;
}
