// 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 "core/fpdfapi/fpdf_page/pageint.h"

#include <algorithm>

#include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"

namespace {

const int kSingleCoordinatePair = 1;
const int kTensorCoordinatePairs = 16;
const int kCoonsCoordinatePairs = 12;

const int kSingleColorPerPatch = 1;
const int kQuadColorsPerPatch = 4;

ShadingType ToShadingType(int type) {
  return (type > static_cast<int>(kInvalidShading) &&
          type < static_cast<int>(kMaxShading))
             ? static_cast<ShadingType>(type)
             : kInvalidShading;
}

}  // namespace

CPDF_Pattern::CPDF_Pattern(PatternType type,
                           CPDF_Document* pDoc,
                           CPDF_Object* pObj,
                           const CFX_Matrix* pParentMatrix)
    : m_PatternType(type),
      m_pDocument(pDoc),
      m_pPatternObj(pObj),
      m_bForceClear(FALSE) {
  if (pParentMatrix)
    m_ParentMatrix = *pParentMatrix;
}
CPDF_Pattern::~CPDF_Pattern() {}
CPDF_TilingPattern::CPDF_TilingPattern(CPDF_Document* pDoc,
                                       CPDF_Object* pPatternObj,
                                       const CFX_Matrix* parentMatrix)
    : CPDF_Pattern(TILING, pDoc, pPatternObj, parentMatrix) {
  CPDF_Dictionary* pDict = m_pPatternObj->GetDict();
  m_Pattern2Form = pDict->GetMatrixBy("Matrix");
  m_bColored = pDict->GetIntegerBy("PaintType") == 1;
  if (parentMatrix) {
    m_Pattern2Form.Concat(*parentMatrix);
  }
  m_pForm = NULL;
}
CPDF_TilingPattern::~CPDF_TilingPattern() {
  delete m_pForm;
  m_pForm = NULL;
}
FX_BOOL CPDF_TilingPattern::Load() {
  if (m_pForm)
    return TRUE;

  CPDF_Dictionary* pDict = m_pPatternObj->GetDict();
  if (!pDict)
    return FALSE;

  m_bColored = pDict->GetIntegerBy("PaintType") == 1;
  m_XStep = (FX_FLOAT)FXSYS_fabs(pDict->GetNumberBy("XStep"));
  m_YStep = (FX_FLOAT)FXSYS_fabs(pDict->GetNumberBy("YStep"));

  CPDF_Stream* pStream = m_pPatternObj->AsStream();
  if (!pStream)
    return FALSE;

  m_pForm = new CPDF_Form(m_pDocument, NULL, pStream);
  m_pForm->ParseContent(NULL, &m_ParentMatrix, NULL, NULL);
  m_BBox = pDict->GetRectBy("BBox");
  return TRUE;
}
CPDF_ShadingPattern::CPDF_ShadingPattern(CPDF_Document* pDoc,
                                         CPDF_Object* pPatternObj,
                                         FX_BOOL bShading,
                                         const CFX_Matrix* parentMatrix)
    : CPDF_Pattern(SHADING,
                   pDoc,
                   bShading ? nullptr : pPatternObj,
                   parentMatrix),
      m_ShadingType(kInvalidShading),
      m_bShadingObj(bShading),
      m_pShadingObj(pPatternObj),
      m_pCS(nullptr),
      m_pCountedCS(nullptr),
      m_nFuncs(0) {
  if (!bShading) {
    CPDF_Dictionary* pDict = m_pPatternObj->GetDict();
    m_Pattern2Form = pDict->GetMatrixBy("Matrix");
    m_pShadingObj = pDict->GetElementValue("Shading");
    if (parentMatrix)
      m_Pattern2Form.Concat(*parentMatrix);
  }
  for (int i = 0; i < FX_ArraySize(m_pFunctions); ++i)
    m_pFunctions[i] = nullptr;
}

CPDF_ShadingPattern::~CPDF_ShadingPattern() {
  for (int i = 0; i < m_nFuncs; ++i)
    delete m_pFunctions[i];

  CPDF_ColorSpace* pCS = m_pCountedCS ? m_pCountedCS->get() : NULL;
  if (pCS && m_pDocument)
    m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray());
}

FX_BOOL CPDF_ShadingPattern::Load() {
  if (m_ShadingType != kInvalidShading)
    return TRUE;

  CPDF_Dictionary* pShadingDict =
      m_pShadingObj ? m_pShadingObj->GetDict() : NULL;
  if (!pShadingDict) {
    return FALSE;
  }
  if (m_nFuncs) {
    for (int i = 0; i < m_nFuncs; i++)
      delete m_pFunctions[i];
    m_nFuncs = 0;
  }
  CPDF_Object* pFunc = pShadingDict->GetElementValue("Function");
  if (pFunc) {
    if (CPDF_Array* pArray = pFunc->AsArray()) {
      m_nFuncs = std::min<int>(pArray->GetCount(), 4);

      for (int i = 0; i < m_nFuncs; i++) {
        m_pFunctions[i] = CPDF_Function::Load(pArray->GetElementValue(i));
      }
    } else {
      m_pFunctions[0] = CPDF_Function::Load(pFunc);
      m_nFuncs = 1;
    }
  }
  CPDF_Object* pCSObj = pShadingDict->GetElementValue("ColorSpace");
  if (!pCSObj) {
    return FALSE;
  }
  CPDF_DocPageData* pDocPageData = m_pDocument->GetPageData();
  m_pCS = pDocPageData->GetColorSpace(pCSObj, NULL);
  if (m_pCS) {
    m_pCountedCS = pDocPageData->FindColorSpacePtr(m_pCS->GetArray());
  }

  m_ShadingType = ToShadingType(pShadingDict->GetIntegerBy("ShadingType"));

  // We expect to have a stream if our shading type is a mesh.
  if (IsMeshShading() && !ToStream(m_pShadingObj))
    return FALSE;

  return TRUE;
}
FX_BOOL CPDF_MeshStream::Load(CPDF_Stream* pShadingStream,
                              CPDF_Function** pFuncs,
                              int nFuncs,
                              CPDF_ColorSpace* pCS) {
  m_Stream.LoadAllData(pShadingStream);
  m_BitStream.Init(m_Stream.GetData(), m_Stream.GetSize());
  m_pFuncs = pFuncs;
  m_nFuncs = nFuncs;
  m_pCS = pCS;
  CPDF_Dictionary* pDict = pShadingStream->GetDict();
  m_nCoordBits = pDict->GetIntegerBy("BitsPerCoordinate");
  m_nCompBits = pDict->GetIntegerBy("BitsPerComponent");
  m_nFlagBits = pDict->GetIntegerBy("BitsPerFlag");
  if (!m_nCoordBits || !m_nCompBits) {
    return FALSE;
  }
  FX_DWORD nComps = pCS->CountComponents();
  if (nComps > 8) {
    return FALSE;
  }
  m_nComps = nFuncs ? 1 : nComps;
  if (((int)m_nComps < 0) || m_nComps > 8) {
    return FALSE;
  }
  m_CoordMax = m_nCoordBits == 32 ? -1 : (1 << m_nCoordBits) - 1;
  m_CompMax = (1 << m_nCompBits) - 1;
  CPDF_Array* pDecode = pDict->GetArrayBy("Decode");
  if (!pDecode || pDecode->GetCount() != 4 + m_nComps * 2) {
    return FALSE;
  }
  m_xmin = pDecode->GetNumberAt(0);
  m_xmax = pDecode->GetNumberAt(1);
  m_ymin = pDecode->GetNumberAt(2);
  m_ymax = pDecode->GetNumberAt(3);
  for (FX_DWORD i = 0; i < m_nComps; i++) {
    m_ColorMin[i] = pDecode->GetNumberAt(i * 2 + 4);
    m_ColorMax[i] = pDecode->GetNumberAt(i * 2 + 5);
  }
  return TRUE;
}
FX_DWORD CPDF_MeshStream::GetFlag() {
  return m_BitStream.GetBits(m_nFlagBits) & 0x03;
}
void CPDF_MeshStream::GetCoords(FX_FLOAT& x, FX_FLOAT& y) {
  if (m_nCoordBits == 32) {
    x = m_xmin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) *
                            (m_xmax - m_xmin) / (double)m_CoordMax);
    y = m_ymin + (FX_FLOAT)(m_BitStream.GetBits(m_nCoordBits) *
                            (m_ymax - m_ymin) / (double)m_CoordMax);
  } else {
    x = m_xmin +
        m_BitStream.GetBits(m_nCoordBits) * (m_xmax - m_xmin) / m_CoordMax;
    y = m_ymin +
        m_BitStream.GetBits(m_nCoordBits) * (m_ymax - m_ymin) / m_CoordMax;
  }
}
void CPDF_MeshStream::GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b) {
  FX_DWORD i;
  FX_FLOAT color_value[8];
  for (i = 0; i < m_nComps; i++) {
    color_value[i] = m_ColorMin[i] +
                     m_BitStream.GetBits(m_nCompBits) *
                         (m_ColorMax[i] - m_ColorMin[i]) / m_CompMax;
  }
  if (m_nFuncs) {
    static const int kMaxResults = 8;
    FX_FLOAT result[kMaxResults];
    int nResults;
    FXSYS_memset(result, 0, sizeof(result));
    for (FX_DWORD i = 0; i < m_nFuncs; i++) {
      if (m_pFuncs[i] && m_pFuncs[i]->CountOutputs() <= kMaxResults) {
        m_pFuncs[i]->Call(color_value, 1, result, nResults);
      }
    }
    m_pCS->GetRGB(result, r, g, b);
  } else {
    m_pCS->GetRGB(color_value, r, g, b);
  }
}
FX_DWORD CPDF_MeshStream::GetVertex(CPDF_MeshVertex& vertex,
                                    CFX_Matrix* pObject2Bitmap) {
  FX_DWORD flag = GetFlag();
  GetCoords(vertex.x, vertex.y);
  pObject2Bitmap->Transform(vertex.x, vertex.y);
  GetColor(vertex.r, vertex.g, vertex.b);
  m_BitStream.ByteAlign();
  return flag;
}
FX_BOOL CPDF_MeshStream::GetVertexRow(CPDF_MeshVertex* vertex,
                                      int count,
                                      CFX_Matrix* pObject2Bitmap) {
  for (int i = 0; i < count; i++) {
    if (m_BitStream.IsEOF()) {
      return FALSE;
    }
    GetCoords(vertex[i].x, vertex[i].y);
    pObject2Bitmap->Transform(vertex[i].x, vertex[i].y);
    GetColor(vertex[i].r, vertex[i].g, vertex[i].b);
    m_BitStream.ByteAlign();
  }
  return TRUE;
}

CFX_FloatRect GetShadingBBox(CPDF_Stream* pStream,
                             ShadingType type,
                             const CFX_Matrix* pMatrix,
                             CPDF_Function** pFuncs,
                             int nFuncs,
                             CPDF_ColorSpace* pCS) {
  if (!pStream || !pStream->IsStream() || !pFuncs || !pCS)
    return CFX_FloatRect(0, 0, 0, 0);

  CPDF_MeshStream stream;
  if (!stream.Load(pStream, pFuncs, nFuncs, pCS))
    return CFX_FloatRect(0, 0, 0, 0);

  CFX_FloatRect rect;
  bool bStarted = false;
  bool bGouraud = type == kFreeFormGouraudTriangleMeshShading ||
                  type == kLatticeFormGouraudTriangleMeshShading;

  int point_count = kSingleCoordinatePair;
  if (type == kTensorProductPatchMeshShading)
    point_count = kTensorCoordinatePairs;
  else if (type == kCoonsPatchMeshShading)
    point_count = kCoonsCoordinatePairs;

  int color_count = kSingleColorPerPatch;
  if (type == kCoonsPatchMeshShading || type == kTensorProductPatchMeshShading)
    color_count = kQuadColorsPerPatch;

  while (!stream.m_BitStream.IsEOF()) {
    FX_DWORD flag = 0;
    if (type != kLatticeFormGouraudTriangleMeshShading)
      flag = stream.GetFlag();

    if (!bGouraud && flag) {
      point_count -= 4;
      color_count -= 2;
    }

    for (int i = 0; i < point_count; i++) {
      FX_FLOAT x, y;
      stream.GetCoords(x, y);
      if (bStarted) {
        rect.UpdateRect(x, y);
      } else {
        rect.InitRect(x, y);
        bStarted = TRUE;
      }
    }
    stream.m_BitStream.SkipBits(stream.m_nComps * stream.m_nCompBits *
                                color_count);
    if (bGouraud)
      stream.m_BitStream.ByteAlign();
  }
  rect.Transform(pMatrix);
  return rect;
}
