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

#ifndef CORE_INCLUDE_FPDFAPI_FPDF_RESOURCE_H_
#define CORE_INCLUDE_FPDFAPI_FPDF_RESOURCE_H_

#include "../fxcrt/fx_system.h"
#include "../fxge/fx_font.h"
#include "fpdf_parser.h"

class CFX_CTTGSUBTable;
class CFX_DIBitmap;
class CFX_Font;
class CFX_SubstFont;
class CPDF_CID2UnicodeMap;
class CPDF_CIDFont;
class CPDF_CMap;
class CPDF_Color;
class CPDF_ColorSpace;
class CPDF_Face;
class CPDF_FontEncoding;
class CPDF_Form;
class CPDF_Function;
class CPDF_Image;
class CPDF_ImageObject;
class CPDF_Page;
class CPDF_Pattern;
class CPDF_RenderContext;
class CPDF_ShadingPattern;
class CPDF_TilingPattern;
class CPDF_ToUnicodeMap;
class CPDF_TrueTypeFont;
class CPDF_Type1Font;
class CPDF_Type3Font;
typedef struct FT_FaceRec_* FXFT_Face;

FX_WCHAR PDF_UnicodeFromAdobeName(const FX_CHAR* name);
CFX_ByteString PDF_AdobeNameFromUnicode(FX_WCHAR unicode);
const FX_CHAR* FCS_GetAltStr(FX_WCHAR unicode);
const FX_CHAR* PDF_CharNameFromPredefinedCharSet(int encoding,
                                                 uint8_t charcode);

FX_WCHAR FT_UnicodeFromCharCode(int encoding, FX_DWORD charcode);
FX_DWORD FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode);
const FX_WORD* PDF_UnicodesForPredefinedCharSet(int encoding);
const FX_CHAR* GetAdobeCharName(int iBaseEncoding,
                                const CFX_ByteString* pCharNames,
                                int charcode);

template <class T>
class CPDF_CountedObject {
 public:
  explicit CPDF_CountedObject(T* ptr) : m_nCount(1), m_pObj(ptr) {}
  void reset(T* ptr) {  // CAUTION: tosses prior ref counts.
    m_nCount = 1;
    m_pObj = ptr;
  }
  void clear() {  // Now you're all weak ptrs ...
    delete m_pObj;
    m_pObj = nullptr;
  }
  T* get() const { return m_pObj; }
  T* AddRef() {
    FXSYS_assert(m_pObj);
    ++m_nCount;
    return m_pObj;
  }
  void RemoveRef() {
    if (m_nCount)
      --m_nCount;
  }
  size_t use_count() const { return m_nCount; }

 protected:
  size_t m_nCount;
  T* m_pObj;
};
using CPDF_CountedColorSpace = CPDF_CountedObject<CPDF_ColorSpace>;
using CPDF_CountedPattern = CPDF_CountedObject<CPDF_Pattern>;
#define PDFFONT_TYPE1 1
#define PDFFONT_TRUETYPE 2
#define PDFFONT_TYPE3 3
#define PDFFONT_CIDFONT 4
#define PDFFONT_FIXEDPITCH 1
#define PDFFONT_SERIF 2
#define PDFFONT_SYMBOLIC 4
#define PDFFONT_SCRIPT 8
#define PDFFONT_NONSYMBOLIC 32
#define PDFFONT_ITALIC 64
#define PDFFONT_ALLCAP 0x10000
#define PDFFONT_SMALLCAP 0x20000
#define PDFFONT_FORCEBOLD 0x40000
#define PDFFONT_USEEXTERNATTR 0x80000
class CPDF_Font {
 public:
  static CPDF_Font* CreateFontF(CPDF_Document* pDoc,
                                CPDF_Dictionary* pFontDict);
  static CPDF_Font* GetStockFont(CPDF_Document* pDoc,
                                 const CFX_ByteStringC& fontname);
  static const FX_DWORD kInvalidCharCode = static_cast<FX_DWORD>(-1);

  virtual ~CPDF_Font();

  bool IsFontType(int fonttype) const { return fonttype == m_FontType; }
  int GetFontType() const { return m_FontType; }

  CFX_ByteString GetFontTypeName() const;

  const CFX_ByteString& GetBaseFont() const { return m_BaseFont; }

  const CFX_SubstFont* GetSubstFont() const { return m_Font.GetSubstFont(); }

  FX_DWORD GetFlags() const { return m_Flags; }

  virtual FX_BOOL IsVertWriting() const;

  CPDF_Type1Font* GetType1Font() const {
    return m_FontType == PDFFONT_TYPE1 ? (CPDF_Type1Font*)(void*)this : NULL;
  }

  CPDF_TrueTypeFont* GetTrueTypeFont() const {
    return m_FontType == PDFFONT_TRUETYPE ? (CPDF_TrueTypeFont*)(void*)this
                                          : NULL;
  }

  CPDF_CIDFont* GetCIDFont() const {
    return (m_FontType == PDFFONT_CIDFONT) ? (CPDF_CIDFont*)(void*)this : NULL;
  }

  CPDF_Type3Font* GetType3Font() const {
    return (m_FontType == PDFFONT_TYPE3) ? (CPDF_Type3Font*)(void*)this : NULL;
  }

  FX_BOOL IsEmbedded() const {
    return m_FontType == PDFFONT_TYPE3 || m_pFontFile != NULL;
  }

  virtual FX_BOOL IsUnicodeCompatible() const { return FALSE; }

  CPDF_StreamAcc* GetFontFile() const { return m_pFontFile; }

  CPDF_Dictionary* GetFontDict() const { return m_pFontDict; }

  FX_BOOL IsStandardFont() const;

  FXFT_Face GetFace() const { return m_Font.GetFace(); }

  virtual FX_DWORD GetNextChar(const FX_CHAR* pString,
                               int nStrLen,
                               int& offset) const {
    if (offset < 0 || nStrLen < 1) {
      return 0;
    }
    uint8_t ch = offset < nStrLen ? pString[offset++] : pString[nStrLen - 1];
    return static_cast<FX_DWORD>(ch);
  }

  virtual int CountChar(const FX_CHAR* pString, int size) const { return size; }

  void AppendChar(CFX_ByteString& str, FX_DWORD charcode) const;

  virtual int AppendChar(FX_CHAR* buf, FX_DWORD charcode) const {
    *buf = (FX_CHAR)charcode;
    return 1;
  }

  virtual int GetCharSize(FX_DWORD charcode) const { return 1; }

  virtual int GlyphFromCharCode(FX_DWORD charcode,
                                FX_BOOL* pVertGlyph = NULL) = 0;
  virtual int GlyphFromCharCodeExt(FX_DWORD charcode) {
    return GlyphFromCharCode(charcode);
  }

  CFX_WideString UnicodeFromCharCode(FX_DWORD charcode) const;

  FX_DWORD CharCodeFromUnicode(FX_WCHAR Unicode) const;

  CFX_CharMap* GetCharMap() { return m_pCharMap; }

  CFX_ByteString EncodeString(const CFX_WideString& str) const;

  CFX_WideString DecodeString(const CFX_ByteString& str) const;

  void GetFontBBox(FX_RECT& rect) const { rect = m_FontBBox; }

  int GetTypeAscent() const { return m_Ascent; }

  int GetTypeDescent() const { return m_Descent; }

  int GetItalicAngle() const { return m_ItalicAngle; }

  int GetStemV() const { return m_StemV; }

  int GetStringWidth(const FX_CHAR* pString, int size);

  virtual int GetCharWidthF(FX_DWORD charcode, int level = 0) = 0;

  virtual int GetCharTypeWidth(FX_DWORD charcode);

  virtual void GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level = 0) = 0;

  CPDF_Document* m_pDocument;

  class CFX_PathData* LoadGlyphPath(FX_DWORD charcode, int dest_width = 0);

  CFX_Font m_Font;

 protected:
  explicit CPDF_Font(int fonttype);

  FX_BOOL Initialize();

  FX_BOOL Load();

  virtual FX_BOOL _Load() = 0;

  virtual FX_WCHAR _UnicodeFromCharCode(FX_DWORD charcode) const = 0;

  virtual FX_DWORD _CharCodeFromUnicode(FX_WCHAR Unicode) const = 0;

  void LoadUnicodeMap();

  void LoadPDFEncoding(CPDF_Object* pEncoding,
                       int& iBaseEncoding,
                       CFX_ByteString*& pCharNames,
                       FX_BOOL bEmbedded,
                       FX_BOOL bTrueType);

  void LoadFontDescriptor(CPDF_Dictionary*);

  void LoadCharWidths(FX_WORD* pWidths);

  void CheckFontMetrics();

  CFX_CharMap* m_pCharMap;

  CFX_ByteString m_BaseFont;

  CPDF_StreamAcc* m_pFontFile;

  CPDF_Dictionary* m_pFontDict;

  CPDF_ToUnicodeMap* m_pToUnicodeMap;

  FX_BOOL m_bToUnicodeLoaded;

  int m_Flags;

  FX_RECT m_FontBBox;

  int m_StemV;

  int m_Ascent;

  int m_Descent;

  int m_ItalicAngle;

 private:
  const int m_FontType;
};
#define PDFFONT_ENCODING_BUILTIN 0
#define PDFFONT_ENCODING_WINANSI 1
#define PDFFONT_ENCODING_MACROMAN 2
#define PDFFONT_ENCODING_MACEXPERT 3
#define PDFFONT_ENCODING_STANDARD 4
#define PDFFONT_ENCODING_ADOBE_SYMBOL 5
#define PDFFONT_ENCODING_ZAPFDINGBATS 6
#define PDFFONT_ENCODING_PDFDOC 7
#define PDFFONT_ENCODING_MS_SYMBOL 8
#define PDFFONT_ENCODING_UNICODE 9
class CPDF_FontEncoding {
 public:
  CPDF_FontEncoding();

  CPDF_FontEncoding(int PredefinedEncoding);

  void LoadEncoding(CPDF_Object* pEncoding);

  FX_BOOL IsIdentical(CPDF_FontEncoding* pAnother) const;

  FX_WCHAR UnicodeFromCharCode(uint8_t charcode) const {
    return m_Unicodes[charcode];
  }

  int CharCodeFromUnicode(FX_WCHAR unicode) const;

  void SetUnicode(uint8_t charcode, FX_WCHAR unicode) {
    m_Unicodes[charcode] = unicode;
  }

  CPDF_Object* Realize();

 public:
  FX_WCHAR m_Unicodes[256];
};

class CPDF_SimpleFont : public CPDF_Font {
 public:
  explicit CPDF_SimpleFont(int fonttype);
  ~CPDF_SimpleFont() override;

  CPDF_FontEncoding* GetEncoding() { return &m_Encoding; }
  int GetCharWidthF(FX_DWORD charcode, int level = 0) override;
  void GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level = 0) override;
  int GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph = NULL) override;
  FX_BOOL IsUnicodeCompatible() const override;

 protected:
  FX_BOOL LoadCommon();

  void LoadSubstFont();

  void LoadFaceMetrics();

  virtual void LoadGlyphMap() = 0;

  FX_WCHAR _UnicodeFromCharCode(FX_DWORD charcode) const override {
    return m_Encoding.UnicodeFromCharCode((uint8_t)charcode);
  }

  FX_DWORD _CharCodeFromUnicode(FX_WCHAR Unicode) const override {
    return m_Encoding.CharCodeFromUnicode(Unicode);
  }

  void LoadCharMetrics(int charcode);

  CPDF_FontEncoding m_Encoding;
  FX_WORD m_GlyphIndex[256];
  FX_WORD m_ExtGID[256];
  CFX_ByteString* m_pCharNames;
  int m_BaseEncoding;
  FX_WORD m_CharWidth[256];
  FX_SMALL_RECT m_CharBBox[256];
  FX_BOOL m_bUseFontWidth;
};

class CPDF_Type1Font : public CPDF_SimpleFont {
 public:
  CPDF_Type1Font();

  int GetBase14Font() { return m_Base14Font; }
  virtual int GlyphFromCharCodeExt(FX_DWORD charcode);

 protected:
  virtual FX_BOOL _Load();

  int m_Base14Font;
  virtual void LoadGlyphMap();
};
class CPDF_TrueTypeFont : public CPDF_SimpleFont {
 public:
  CPDF_TrueTypeFont();

 protected:
  virtual FX_BOOL _Load();
  virtual void LoadGlyphMap();
};
class CPDF_Type3Char {
 public:
  CPDF_Type3Char();

  ~CPDF_Type3Char();

  FX_BOOL LoadBitmap(CPDF_RenderContext* pContext);

  FX_BOOL m_bColored;

  FX_BOOL m_bPageRequired;

  CPDF_Form* m_pForm;

  CFX_AffineMatrix m_ImageMatrix;

  CFX_DIBitmap* m_pBitmap;

  int m_Width;

  FX_RECT m_BBox;
};
class CPDF_Type3Font : public CPDF_SimpleFont {
 public:
  CPDF_Type3Font();
  ~CPDF_Type3Font() override;

  void SetPageResources(CPDF_Dictionary* pResources) {
    m_pPageResources = pResources;
  }
  CPDF_Type3Char* LoadChar(FX_DWORD charcode, int level = 0);
  int GetCharWidthF(FX_DWORD charcode, int level = 0) override;
  int GetCharTypeWidth(FX_DWORD charcode) override {
    return GetCharWidthF(charcode);
  }
  void GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level = 0) override;
  CFX_AffineMatrix& GetFontMatrix() { return m_FontMatrix; }
  void CheckType3FontMetrics();

 protected:
  CFX_AffineMatrix m_FontMatrix;

 private:
  FX_BOOL _Load() override;
  void LoadGlyphMap() override {}

  int m_CharWidthL[256];
  CPDF_Dictionary* m_pCharProcs;
  CPDF_Dictionary* m_pPageResources;
  CPDF_Dictionary* m_pFontResources;
  CFX_MapPtrToPtr m_CacheMap;
  CFX_MapPtrToPtr m_DeletedMap;
};

#define CIDSET_UNKNOWN 0
#define CIDSET_GB1 1
#define CIDSET_CNS1 2
#define CIDSET_JAPAN1 3
#define CIDSET_KOREA1 4
#define CIDSET_UNICODE 5
#define NUMBER_OF_CIDSETS 6

class CPDF_CIDFont : public CPDF_Font {
 public:
  CPDF_CIDFont();

  ~CPDF_CIDFont() override;

  FX_BOOL LoadGB2312();
  int GlyphFromCharCode(FX_DWORD charcode, FX_BOOL* pVertGlyph = NULL) override;
  int GetCharWidthF(FX_DWORD charcode, int level = 0) override;
  void GetCharBBox(FX_DWORD charcode, FX_RECT& rect, int level = 0) override;
  FX_WORD CIDFromCharCode(FX_DWORD charcode) const;

  FX_BOOL IsTrueType() const { return !m_bType1; }

  virtual FX_DWORD GetNextChar(const FX_CHAR* pString,
                               int nStrLen,
                               int& offset) const override;
  int CountChar(const FX_CHAR* pString, int size) const override;
  int AppendChar(FX_CHAR* str, FX_DWORD charcode) const override;
  int GetCharSize(FX_DWORD charcode) const override;

  int GetCharset() const { return m_Charset; }

  const uint8_t* GetCIDTransform(FX_WORD CID) const;
  FX_BOOL IsVertWriting() const override;
  short GetVertWidth(FX_WORD CID) const;
  void GetVertOrigin(FX_WORD CID, short& vx, short& vy) const;
  FX_BOOL IsUnicodeCompatible() const override;
  virtual FX_BOOL IsFontStyleFromCharCode(FX_DWORD charcode) const;

 protected:
  friend class CPDF_Font;

  FX_BOOL _Load() override;
  FX_WCHAR _UnicodeFromCharCode(FX_DWORD charcode) const override;
  FX_DWORD _CharCodeFromUnicode(FX_WCHAR Unicode) const override;
  int GetGlyphIndex(FX_DWORD unicodeb, FX_BOOL* pVertGlyph);
  void LoadMetricsArray(CPDF_Array* pArray,
                        CFX_DWordArray& result,
                        int nElements);
  void LoadSubstFont();

  CPDF_CMap* m_pCMap;
  CPDF_CMap* m_pAllocatedCMap;
  CPDF_CID2UnicodeMap* m_pCID2UnicodeMap;
  int m_Charset;
  FX_BOOL m_bType1;
  CPDF_StreamAcc* m_pCIDToGIDMap;
  FX_BOOL m_bCIDIsGID;
  FX_WORD m_DefaultWidth;
  FX_WORD* m_pAnsiWidths;
  FX_SMALL_RECT m_CharBBox[256];
  CFX_DWordArray m_WidthList;
  short m_DefaultVY;
  short m_DefaultW1;
  CFX_DWordArray m_VertMetrics;
  FX_BOOL m_bAdobeCourierStd;
  CFX_CTTGSUBTable* m_pTTGSUBTable;
};

#define PDFCS_DEVICEGRAY 1
#define PDFCS_DEVICERGB 2
#define PDFCS_DEVICECMYK 3
#define PDFCS_CALGRAY 4
#define PDFCS_CALRGB 5
#define PDFCS_LAB 6
#define PDFCS_ICCBASED 7
#define PDFCS_SEPARATION 8
#define PDFCS_DEVICEN 9
#define PDFCS_INDEXED 10
#define PDFCS_PATTERN 11

class CPDF_ColorSpace {
 public:
  static CPDF_ColorSpace* GetStockCS(int Family);

  static CPDF_ColorSpace* Load(CPDF_Document* pDoc, CPDF_Object* pCSObj);

  void ReleaseCS();

  int GetBufSize() const;

  FX_FLOAT* CreateBuf();

  void GetDefaultColor(FX_FLOAT* buf) const;

  int CountComponents() const { return m_nComponents; }

  int GetFamily() const { return m_Family; }

  virtual void GetDefaultValue(int iComponent,
                               FX_FLOAT& value,
                               FX_FLOAT& min,
                               FX_FLOAT& max) const {
    value = 0;
    min = 0;
    max = 1.0f;
  }

  FX_BOOL sRGB() const;

  virtual FX_BOOL GetRGB(FX_FLOAT* pBuf,
                         FX_FLOAT& R,
                         FX_FLOAT& G,
                         FX_FLOAT& B) const = 0;

  virtual FX_BOOL SetRGB(FX_FLOAT* pBuf,
                         FX_FLOAT R,
                         FX_FLOAT G,
                         FX_FLOAT B) const {
    return FALSE;
  }

  FX_BOOL GetCMYK(FX_FLOAT* pBuf,
                  FX_FLOAT& c,
                  FX_FLOAT& m,
                  FX_FLOAT& y,
                  FX_FLOAT& k) const;

  FX_BOOL SetCMYK(FX_FLOAT* pBuf,
                  FX_FLOAT c,
                  FX_FLOAT m,
                  FX_FLOAT y,
                  FX_FLOAT k) const;

  virtual void TranslateImageLine(uint8_t* dest_buf,
                                  const uint8_t* src_buf,
                                  int pixels,
                                  int image_width,
                                  int image_height,
                                  FX_BOOL bTransMask = FALSE) const;

  CPDF_Array*& GetArray() { return m_pArray; }

  int GetMaxIndex() const;

  virtual CPDF_ColorSpace* GetBaseCS() const { return NULL; }

  virtual void EnableStdConversion(FX_BOOL bEnabled);

  CPDF_Document* const m_pDocument;

 protected:
  CPDF_ColorSpace(CPDF_Document* pDoc, int family, int nComponents)
      : m_pDocument(pDoc),
        m_Family(family),
        m_nComponents(nComponents),
        m_pArray(nullptr),
        m_dwStdConversion(0) {}
  virtual ~CPDF_ColorSpace() {}
  virtual FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) {
    return TRUE;
  }
  virtual FX_BOOL v_GetCMYK(FX_FLOAT* pBuf,
                            FX_FLOAT& c,
                            FX_FLOAT& m,
                            FX_FLOAT& y,
                            FX_FLOAT& k) const {
    return FALSE;
  }
  virtual FX_BOOL v_SetCMYK(FX_FLOAT* pBuf,
                            FX_FLOAT c,
                            FX_FLOAT m,
                            FX_FLOAT y,
                            FX_FLOAT k) const {
    return FALSE;
  }

  int m_Family;

  int m_nComponents;

  CPDF_Array* m_pArray;

  FX_DWORD m_dwStdConversion;
};
class CPDF_Color {
 public:
  CPDF_Color() : m_pCS(NULL), m_pBuffer(NULL) {}

  CPDF_Color(int family);

  ~CPDF_Color();

  FX_BOOL IsNull() const { return m_pBuffer == NULL; }

  FX_BOOL IsEqual(const CPDF_Color& other) const;

  FX_BOOL IsPattern() const {
    return m_pCS && m_pCS->GetFamily() == PDFCS_PATTERN;
  }

  void Copy(const CPDF_Color* pSrc);

  void SetColorSpace(CPDF_ColorSpace* pCS);

  void SetValue(FX_FLOAT* comp);

  void SetValue(CPDF_Pattern* pPattern, FX_FLOAT* comp, int ncomps);

  FX_BOOL GetRGB(int& R, int& G, int& B) const;

  CPDF_Pattern* GetPattern() const;

  CPDF_ColorSpace* GetPatternCS() const;

  FX_FLOAT* GetPatternColor() const;

  CPDF_ColorSpace* m_pCS;

 protected:
  void ReleaseBuffer();
  void ReleaseColorSpace();
  FX_FLOAT* m_pBuffer;
};
#define PATTERN_TILING 1
#define PATTERN_SHADING 2
class CPDF_Pattern {
 public:
  virtual ~CPDF_Pattern();
  void SetForceClear(FX_BOOL bForceClear) { m_bForceClear = bForceClear; }

  CPDF_Object* m_pPatternObj;

  int m_PatternType;

  CFX_AffineMatrix m_Pattern2Form;
  CFX_AffineMatrix m_ParentMatrix;

  CPDF_Document* m_pDocument;

 protected:
  CPDF_Pattern(const CFX_AffineMatrix* pParentMatrix);
  FX_BOOL m_bForceClear;
};

class CPDF_TilingPattern : public CPDF_Pattern {
 public:
  CPDF_TilingPattern(CPDF_Document* pDoc,
                     CPDF_Object* pPatternObj,
                     const CFX_AffineMatrix* parentMatrix);

  ~CPDF_TilingPattern() override;

  FX_BOOL Load();

  FX_BOOL m_bColored;

  CFX_FloatRect m_BBox;

  FX_FLOAT m_XStep;

  FX_FLOAT m_YStep;

  CPDF_Form* m_pForm;
};
class CPDF_ShadingPattern : public CPDF_Pattern {
 public:
  CPDF_ShadingPattern(CPDF_Document* pDoc,
                      CPDF_Object* pPatternObj,
                      FX_BOOL bShading,
                      const CFX_AffineMatrix* parentMatrix);

  ~CPDF_ShadingPattern() override;

  CPDF_Object* m_pShadingObj;

  FX_BOOL m_bShadingObj;

  FX_BOOL Load();

  FX_BOOL Reload();

  int m_ShadingType;

  CPDF_ColorSpace* m_pCS;  // Still keep m_pCS as some CPDF_ColorSpace (name
                           // object) are not managed as counted objects. Refer
                           // to CPDF_DocPageData::GetColorSpace.

  CPDF_CountedColorSpace* m_pCountedCS;

  CPDF_Function* m_pFunctions[4];

  int m_nFuncs;

 protected:
  void Clear();
};
struct CPDF_MeshVertex {
  FX_FLOAT x, y;
  FX_FLOAT r, g, b;
};
class CPDF_MeshStream {
 public:
  FX_BOOL Load(CPDF_Stream* pShadingStream,
               CPDF_Function** pFuncs,
               int nFuncs,
               CPDF_ColorSpace* pCS);

  FX_DWORD GetFlag();

  void GetCoords(FX_FLOAT& x, FX_FLOAT& y);

  void GetColor(FX_FLOAT& r, FX_FLOAT& g, FX_FLOAT& b);

  FX_DWORD GetVertex(CPDF_MeshVertex& vertex, CFX_AffineMatrix* pObject2Bitmap);

  FX_BOOL GetVertexRow(CPDF_MeshVertex* vertex,
                       int count,
                       CFX_AffineMatrix* pObject2Bitmap);
  CPDF_Function** m_pFuncs;
  CPDF_ColorSpace* m_pCS;
  FX_DWORD m_nFuncs, m_nCoordBits, m_nCompBits, m_nFlagBits, m_nComps;
  FX_DWORD m_CoordMax, m_CompMax;
  FX_FLOAT m_xmin, m_xmax, m_ymin, m_ymax;
  FX_FLOAT m_ColorMin[8], m_ColorMax[8];
  CPDF_StreamAcc m_Stream;
  CFX_BitStream m_BitStream;
};
#define PDF_IMAGE_NO_COMPRESS 0x0000
#define PDF_IMAGE_LOSSY_COMPRESS 0x0001
#define PDF_IMAGE_LOSSLESS_COMPRESS 0x0002
#define PDF_IMAGE_MASK_LOSSY_COMPRESS 0x0004
#define PDF_IMAGE_MASK_LOSSLESS_COMPRESS 0x0008
class CPDF_ImageSetParam {
 public:
  CPDF_ImageSetParam() : pMatteColor(NULL), nQuality(80) {}
  FX_ARGB* pMatteColor;
  int32_t nQuality;
};
class CPDF_Image {
 public:
  CPDF_Image(CPDF_Document* pDoc);

  ~CPDF_Image();

  FX_BOOL LoadImageF(CPDF_Stream* pImageStream, FX_BOOL bInline);

  void Release();

  CPDF_Image* Clone();

  FX_BOOL IsInline() { return m_bInline; }

  void SetInlineDict(CPDF_Dictionary* pDict) { m_pInlineDict = pDict; }

  CPDF_Dictionary* GetInlineDict() const { return m_pInlineDict; }

  CPDF_Stream* GetStream() const { return m_pStream; }

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

  CPDF_Dictionary* GetOC() const { return m_pOC; }

  CPDF_Document* GetDocument() const { return m_pDocument; }

  int32_t GetPixelHeight() const { return m_Height; }

  int32_t GetPixelWidth() const { return m_Width; }

  FX_BOOL IsMask() const { return m_bIsMask; }

  FX_BOOL IsInterpol() const { return m_bInterpolate; }

  CFX_DIBSource* LoadDIBSource(CFX_DIBSource** ppMask = NULL,
                               FX_DWORD* pMatteColor = NULL,
                               FX_BOOL bStdCS = FALSE,
                               FX_DWORD GroupFamily = 0,
                               FX_BOOL bLoadMask = FALSE) const;

  void SetImage(const CFX_DIBitmap* pDIBitmap,
                int32_t iCompress,
                IFX_FileWrite* pFileWrite = NULL,
                IFX_FileRead* pFileRead = NULL,
                const CFX_DIBitmap* pMask = NULL,
                const CPDF_ImageSetParam* pParam = NULL);

  void SetJpegImage(uint8_t* pImageData, FX_DWORD size);

  void SetJpegImage(IFX_FileRead* pFile);

  void ResetCache(CPDF_Page* pPage, const CFX_DIBitmap* pDIBitmap);

 public:
  FX_BOOL StartLoadDIBSource(CPDF_Dictionary* pFormResource,
                             CPDF_Dictionary* pPageResource,
                             FX_BOOL bStdCS = FALSE,
                             FX_DWORD GroupFamily = 0,
                             FX_BOOL bLoadMask = FALSE);
  FX_BOOL Continue(IFX_Pause* pPause);
  CFX_DIBSource* DetachBitmap();
  CFX_DIBSource* DetachMask();
  CFX_DIBSource* m_pDIBSource;
  CFX_DIBSource* m_pMask;
  FX_DWORD m_MatteColor;

 private:
  CPDF_Stream* m_pStream;
  FX_BOOL m_bInline;
  CPDF_Dictionary* m_pInlineDict;

  int32_t m_Height;

  int32_t m_Width;

  FX_BOOL m_bIsMask;

  FX_BOOL m_bInterpolate;

  CPDF_Document* m_pDocument;

  CPDF_Dictionary* m_pOC;
  CPDF_Dictionary* InitJPEG(uint8_t* pData, FX_DWORD size);
};

#endif  // CORE_INCLUDE_FPDFAPI_FPDF_RESOURCE_H_
