// 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 "../../../include/fpdfapi/fpdf_render.h"
#include "../../../include/fpdfapi/fpdf_pageobj.h"
#include "../../../include/fxge/fx_ge.h"
#include "../fpdf_page/pageint.h"
#include "render_int.h"
struct CACHEINFO {
  FX_DWORD time;
  CPDF_Stream* pStream;
};
extern "C" {
static int compare(const void* data1, const void* data2) {
  return ((CACHEINFO*)data1)->time - ((CACHEINFO*)data2)->time;
}
};
void CPDF_Page::ClearRenderCache() {
  if (m_pPageRender) {
    m_pPageRender->ClearAll();
  }
}
void CPDF_PageRenderCache::ClearAll() {
  FX_POSITION pos = m_ImageCaches.GetStartPosition();
  while (pos) {
    void* key;
    void* value;
    m_ImageCaches.GetNextAssoc(pos, key, value);
    delete (CPDF_ImageCache*)value;
  }
  m_ImageCaches.RemoveAll();
  m_nCacheSize = 0;
  m_nTimeCount = 0;
}
void CPDF_PageRenderCache::CacheOptimization(int32_t dwLimitCacheSize) {
  if (m_nCacheSize <= (FX_DWORD)dwLimitCacheSize) {
    return;
  }
  int nCount = m_ImageCaches.GetCount();
  CACHEINFO* pCACHEINFO =
      (CACHEINFO*)FX_Alloc2D(uint8_t, sizeof(CACHEINFO), nCount);
  FX_POSITION pos = m_ImageCaches.GetStartPosition();
  int i = 0;
  while (pos) {
    void* key;
    void* value;
    m_ImageCaches.GetNextAssoc(pos, key, value);
    pCACHEINFO[i].time = ((CPDF_ImageCache*)value)->GetTimeCount();
    pCACHEINFO[i++].pStream = ((CPDF_ImageCache*)value)->GetStream();
  }
  FXSYS_qsort(pCACHEINFO, nCount, sizeof(CACHEINFO), compare);
  FX_DWORD nTimeCount = m_nTimeCount;
  if (nTimeCount + 1 < nTimeCount) {
    for (i = 0; i < nCount; i++) {
      ((CPDF_ImageCache*)(m_ImageCaches[pCACHEINFO[i].pStream]))
          ->m_dwTimeCount = i;
    }
    m_nTimeCount = nCount;
  }
  i = 0;
  while (nCount > 15) {
    ClearImageCache(pCACHEINFO[i++].pStream);
    nCount--;
  }
  while (m_nCacheSize > (FX_DWORD)dwLimitCacheSize) {
    ClearImageCache(pCACHEINFO[i++].pStream);
  }
  FX_Free(pCACHEINFO);
}
void CPDF_PageRenderCache::ClearImageCache(CPDF_Stream* pStream) {
  void* value = m_ImageCaches.GetValueAt(pStream);
  if (value == NULL) {
    m_ImageCaches.RemoveKey(pStream);
    return;
  }
  m_nCacheSize -= ((CPDF_ImageCache*)value)->EstimateSize();
  delete (CPDF_ImageCache*)value;
  m_ImageCaches.RemoveKey(pStream);
}
FX_DWORD CPDF_PageRenderCache::EstimateSize() {
  FX_DWORD dwSize = 0;
  FX_POSITION pos = m_ImageCaches.GetStartPosition();
  while (pos) {
    void* key;
    void* value;
    m_ImageCaches.GetNextAssoc(pos, key, value);
    dwSize += ((CPDF_ImageCache*)value)->EstimateSize();
  }
  m_nCacheSize = dwSize;
  return dwSize;
}
FX_DWORD CPDF_PageRenderCache::GetCachedSize(CPDF_Stream* pStream) const {
  if (pStream == NULL) {
    return m_nCacheSize;
  }
  CPDF_ImageCache* pImageCache;
  if (!m_ImageCaches.Lookup(pStream, (void*&)pImageCache)) {
    return 0;
  }
  return pImageCache->EstimateSize();
}
void CPDF_PageRenderCache::GetCachedBitmap(CPDF_Stream* pStream,
                                           CFX_DIBSource*& pBitmap,
                                           CFX_DIBSource*& pMask,
                                           FX_DWORD& MatteColor,
                                           FX_BOOL bStdCS,
                                           FX_DWORD GroupFamily,
                                           FX_BOOL bLoadMask,
                                           CPDF_RenderStatus* pRenderStatus,
                                           int32_t downsampleWidth,
                                           int32_t downsampleHeight) {
  CPDF_ImageCache* pImageCache;
  FX_BOOL bFind = m_ImageCaches.Lookup(pStream, (void*&)pImageCache);
  if (!bFind) {
    pImageCache = new CPDF_ImageCache(m_pPage->m_pDocument, pStream);
  }
  m_nTimeCount++;
  FX_BOOL bCached = pImageCache->GetCachedBitmap(
      pBitmap, pMask, MatteColor, m_pPage->m_pPageResources, bStdCS,
      GroupFamily, bLoadMask, pRenderStatus, downsampleWidth, downsampleHeight);
  if (!bFind) {
    m_ImageCaches.SetAt(pStream, pImageCache);
  }
  if (!bCached) {
    m_nCacheSize += pImageCache->EstimateSize();
  }
}
FX_BOOL CPDF_PageRenderCache::StartGetCachedBitmap(
    CPDF_Stream* pStream,
    FX_BOOL bStdCS,
    FX_DWORD GroupFamily,
    FX_BOOL bLoadMask,
    CPDF_RenderStatus* pRenderStatus,
    int32_t downsampleWidth,
    int32_t downsampleHeight) {
  m_bCurFindCache = m_ImageCaches.Lookup(pStream, (void*&)m_pCurImageCache);
  if (!m_bCurFindCache) {
    m_pCurImageCache = new CPDF_ImageCache(m_pPage->m_pDocument, pStream);
  }
  int ret = m_pCurImageCache->StartGetCachedBitmap(
      pRenderStatus->m_pFormResource, m_pPage->m_pPageResources, bStdCS,
      GroupFamily, bLoadMask, pRenderStatus, downsampleWidth, downsampleHeight);
  if (ret == 2) {
    return TRUE;
  }
  m_nTimeCount++;
  if (!m_bCurFindCache) {
    m_ImageCaches.SetAt(pStream, m_pCurImageCache);
  }
  if (!ret) {
    m_nCacheSize += m_pCurImageCache->EstimateSize();
  }
  return FALSE;
}
FX_BOOL CPDF_PageRenderCache::Continue(IFX_Pause* pPause) {
  int ret = m_pCurImageCache->Continue(pPause);
  if (ret == 2) {
    return TRUE;
  }
  m_nTimeCount++;
  if (!m_bCurFindCache) {
    m_ImageCaches.SetAt(m_pCurImageCache->GetStream(), m_pCurImageCache);
  }
  if (!ret) {
    m_nCacheSize += m_pCurImageCache->EstimateSize();
  }
  return FALSE;
}
void CPDF_PageRenderCache::ResetBitmap(CPDF_Stream* pStream,
                                       const CFX_DIBitmap* pBitmap) {
  CPDF_ImageCache* pImageCache;
  if (!m_ImageCaches.Lookup(pStream, (void*&)pImageCache)) {
    if (pBitmap == NULL) {
      return;
    }
    pImageCache = new CPDF_ImageCache(m_pPage->m_pDocument, pStream);
    m_ImageCaches.SetAt(pStream, pImageCache);
  }
  int oldsize = pImageCache->EstimateSize();
  pImageCache->Reset(pBitmap);
  m_nCacheSize = pImageCache->EstimateSize() - oldsize;
}
CPDF_ImageCache::CPDF_ImageCache(CPDF_Document* pDoc, CPDF_Stream* pStream)
    : m_dwTimeCount(0),
      m_pCurBitmap(NULL),
      m_pCurMask(NULL),
      m_MatteColor(0),
      m_pRenderStatus(NULL),
      m_pDocument(pDoc),
      m_pStream(pStream),
      m_pCachedBitmap(NULL),
      m_pCachedMask(NULL),
      m_dwCacheSize(0) {}
CPDF_ImageCache::~CPDF_ImageCache() {
  delete m_pCachedBitmap;
  m_pCachedBitmap = NULL;
  delete m_pCachedMask;
  m_pCachedMask = NULL;
}
void CPDF_ImageCache::Reset(const CFX_DIBitmap* pBitmap) {
  delete m_pCachedBitmap;
  m_pCachedBitmap = NULL;
  if (pBitmap) {
    m_pCachedBitmap = pBitmap->Clone();
  }
  CalcSize();
}
void CPDF_PageRenderCache::ClearImageData() {
  FX_POSITION pos = m_ImageCaches.GetStartPosition();
  while (pos) {
    void* key;
    void* value;
    m_ImageCaches.GetNextAssoc(pos, key, value);
    ((CPDF_ImageCache*)value)->ClearImageData();
  }
}
void CPDF_ImageCache::ClearImageData() {
  if (m_pCachedBitmap && m_pCachedBitmap->GetBuffer() == NULL) {
    ((CPDF_DIBSource*)m_pCachedBitmap)->ClearImageData();
  }
}
static FX_DWORD FPDF_ImageCache_EstimateImageSize(const CFX_DIBSource* pDIB) {
  return pDIB && pDIB->GetBuffer()
             ? (FX_DWORD)pDIB->GetHeight() * pDIB->GetPitch() +
                   (FX_DWORD)pDIB->GetPaletteSize() * 4
             : 0;
}
FX_BOOL CPDF_ImageCache::GetCachedBitmap(CFX_DIBSource*& pBitmap,
                                         CFX_DIBSource*& pMask,
                                         FX_DWORD& MatteColor,
                                         CPDF_Dictionary* pPageResources,
                                         FX_BOOL bStdCS,
                                         FX_DWORD GroupFamily,
                                         FX_BOOL bLoadMask,
                                         CPDF_RenderStatus* pRenderStatus,
                                         int32_t downsampleWidth,
                                         int32_t downsampleHeight) {
  if (m_pCachedBitmap) {
    pBitmap = m_pCachedBitmap;
    pMask = m_pCachedMask;
    MatteColor = m_MatteColor;
    return TRUE;
  }
  if (!pRenderStatus) {
    return FALSE;
  }
  CPDF_RenderContext* pContext = pRenderStatus->GetContext();
  CPDF_PageRenderCache* pPageRenderCache = pContext->m_pPageCache;
  m_dwTimeCount = pPageRenderCache->GetTimeCount();
  CPDF_DIBSource* pSrc = new CPDF_DIBSource;
  CPDF_DIBSource* pMaskSrc = NULL;
  if (!pSrc->Load(m_pDocument, m_pStream, &pMaskSrc, &MatteColor,
                  pRenderStatus->m_pFormResource, pPageResources, bStdCS,
                  GroupFamily, bLoadMask)) {
    delete pSrc;
    pBitmap = NULL;
    return FALSE;
  }
  m_MatteColor = MatteColor;
  if (pSrc->GetPitch() * pSrc->GetHeight() < FPDF_HUGE_IMAGE_SIZE) {
    m_pCachedBitmap = pSrc->Clone();
    delete pSrc;
  } else {
    m_pCachedBitmap = pSrc;
  }
  if (pMaskSrc) {
    m_pCachedMask = pMaskSrc->Clone();
    delete pMaskSrc;
  }

  pBitmap = m_pCachedBitmap;
  pMask = m_pCachedMask;
  CalcSize();
  return FALSE;
}
CFX_DIBSource* CPDF_ImageCache::DetachBitmap() {
  CFX_DIBSource* pDIBSource = m_pCurBitmap;
  m_pCurBitmap = NULL;
  return pDIBSource;
}
CFX_DIBSource* CPDF_ImageCache::DetachMask() {
  CFX_DIBSource* pDIBSource = m_pCurMask;
  m_pCurMask = NULL;
  return pDIBSource;
}
int CPDF_ImageCache::StartGetCachedBitmap(CPDF_Dictionary* pFormResources,
                                          CPDF_Dictionary* pPageResources,
                                          FX_BOOL bStdCS,
                                          FX_DWORD GroupFamily,
                                          FX_BOOL bLoadMask,
                                          CPDF_RenderStatus* pRenderStatus,
                                          int32_t downsampleWidth,
                                          int32_t downsampleHeight) {
  if (m_pCachedBitmap) {
    m_pCurBitmap = m_pCachedBitmap;
    m_pCurMask = m_pCachedMask;
    return 1;
  }
  if (!pRenderStatus) {
    return 0;
  }
  m_pRenderStatus = pRenderStatus;
  m_pCurBitmap = new CPDF_DIBSource;
  int ret =
      ((CPDF_DIBSource*)m_pCurBitmap)
          ->StartLoadDIBSource(m_pDocument, m_pStream, TRUE, pFormResources,
                               pPageResources, bStdCS, GroupFamily, bLoadMask);
  if (ret == 2) {
    return ret;
  }
  if (!ret) {
    delete m_pCurBitmap;
    m_pCurBitmap = NULL;
    return 0;
  }
  ContinueGetCachedBitmap();
  return 0;
}
int CPDF_ImageCache::ContinueGetCachedBitmap() {
  m_MatteColor = ((CPDF_DIBSource*)m_pCurBitmap)->m_MatteColor;
  m_pCurMask = ((CPDF_DIBSource*)m_pCurBitmap)->DetachMask();
  CPDF_RenderContext* pContext = m_pRenderStatus->GetContext();
  CPDF_PageRenderCache* pPageRenderCache = pContext->m_pPageCache;
  m_dwTimeCount = pPageRenderCache->GetTimeCount();
  if (m_pCurBitmap->GetPitch() * m_pCurBitmap->GetHeight() <
      FPDF_HUGE_IMAGE_SIZE) {
    m_pCachedBitmap = m_pCurBitmap->Clone();
    delete m_pCurBitmap;
    m_pCurBitmap = NULL;
  } else {
    m_pCachedBitmap = m_pCurBitmap;
  }
  if (m_pCurMask) {
    m_pCachedMask = m_pCurMask->Clone();
    delete m_pCurMask;
    m_pCurMask = NULL;
  }
  m_pCurBitmap = m_pCachedBitmap;
  m_pCurMask = m_pCachedMask;
  CalcSize();
  return 0;
}
int CPDF_ImageCache::Continue(IFX_Pause* pPause) {
  int ret = ((CPDF_DIBSource*)m_pCurBitmap)->ContinueLoadDIBSource(pPause);
  if (ret == 2) {
    return ret;
  }
  if (!ret) {
    delete m_pCurBitmap;
    m_pCurBitmap = NULL;
    return 0;
  }
  ContinueGetCachedBitmap();
  return 0;
}
void CPDF_ImageCache::CalcSize() {
  m_dwCacheSize = FPDF_ImageCache_EstimateImageSize(m_pCachedBitmap) +
                  FPDF_ImageCache_EstimateImageSize(m_pCachedMask);
}
void CPDF_Document::ClearRenderFont() {
  if (m_pDocRender) {
    CFX_FontCache* pCache = m_pDocRender->GetFontCache();
    if (pCache) {
      pCache->FreeCache(FALSE);
    }
  }
}
