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

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
FX_WCHAR PDF_UnicodeFromAdobeName(const FX_CHAR* name);
CFX_ByteString PDF_AdobeNameFromUnicode(FX_WCHAR unicode);
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);

    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);

    virtual ~CPDF_TilingPattern();

    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);

    virtual ~CPDF_ShadingPattern();

    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_
