// 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 _FPDF_PAGEOBJ_H_
#include "../../../include/fpdfapi/fpdf_pageobj.h"
#endif
class CPDF_QuickStretcher;
#define TYPE3_MAX_BLUES		16
class CPDF_Type3Glyphs : public CFX_Object
{
public:
    CPDF_Type3Glyphs()
    {
        m_GlyphMap.InitHashTable(253);
        m_TopBlueCount = m_BottomBlueCount = 0;
    }
    ~CPDF_Type3Glyphs();
    CFX_MapPtrToPtr			m_GlyphMap;
    void					AdjustBlue(FX_FLOAT top, FX_FLOAT bottom, int& top_line, int& bottom_line);

    int						m_TopBlue[TYPE3_MAX_BLUES], m_BottomBlue[TYPE3_MAX_BLUES];
    int						m_TopBlueCount, m_BottomBlueCount;
};
class CFX_GlyphBitmap;
class CPDF_Type3Cache : public CFX_Object
{
public:
    CPDF_Type3Cache(CPDF_Type3Font* pFont)
    {
        m_pFont = pFont;
    }
    ~CPDF_Type3Cache();
    CFX_GlyphBitmap*		LoadGlyph(FX_DWORD charcode, const CFX_AffineMatrix* pMatrix, FX_FLOAT retinaScaleX = 1.0f, FX_FLOAT retinaScaleY = 1.0f);
protected:
    CFX_GlyphBitmap*		RenderGlyph(CPDF_Type3Glyphs* pSize, FX_DWORD charcode, const CFX_AffineMatrix* pMatrix, FX_FLOAT retinaScaleX = 1.0f, FX_FLOAT retinaScaleY = 1.0f);
    CPDF_Type3Font*			m_pFont;
    CFX_MapByteStringToPtr	m_SizeMap;
};
class CPDF_TransferFunc : public CFX_Object
{
public:
    CPDF_Document*	m_pPDFDoc;
    FX_BYTE			m_Samples[256 * 3];
    FX_BOOL			m_bIdentity;

    CFX_DIBSource*	TranslateImage(const CFX_DIBSource* pSrc, FX_BOOL bAutoDropSrc);
    FX_COLORREF		TranslateColor(FX_COLORREF src);
};
typedef CFX_MapPtrTemplate<CPDF_Font*, CPDF_CountedObject<CPDF_Type3Cache*>*> CPDF_Type3CacheMap;
typedef CFX_MapPtrTemplate<CPDF_Object*, CPDF_CountedObject<CPDF_TransferFunc*>*> CPDF_TransferFuncMap;
class CPDF_DocRenderData : public CFX_Object
{
public:
    CPDF_DocRenderData(CPDF_Document* pPDFDoc = NULL);
    ~CPDF_DocRenderData();
    FX_BOOL				Initialize();
    CPDF_Type3Cache*	GetCachedType3(CPDF_Type3Font* pFont);
    CPDF_TransferFunc*	GetTransferFunc(CPDF_Object* pObj);
    CFX_FontCache*		GetFontCache()
    {
        return m_pFontCache;
    }
    void				Clear(FX_BOOL bRelease = FALSE);
    void				ReleaseCachedType3(CPDF_Type3Font* pFont);
    void				ReleaseTransferFunc(CPDF_Object* pObj);
private:
    CPDF_Document*		m_pPDFDoc;
    CFX_FontCache*		m_pFontCache;
    CPDF_Type3CacheMap	m_Type3FaceMap;
    CPDF_TransferFuncMap	m_TransferFuncMap;
};
struct _PDF_RenderItem {
public:
    CPDF_PageObjects*			m_pObjectList;
    CFX_AffineMatrix			m_Matrix;
};
typedef CFX_ArrayTemplate<_PDF_RenderItem>	CPDF_RenderLayer;
class IPDF_ObjectRenderer : public CFX_Object
{
public:
    static IPDF_ObjectRenderer* Create(int type);
    virtual ~IPDF_ObjectRenderer() {}
    virtual FX_BOOL Start(CPDF_RenderStatus* pRenderStatus, const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStdCS, int blendType = FXDIB_BLEND_NORMAL) = 0;
    virtual FX_BOOL Continue(IFX_Pause* pPause) = 0;
    FX_BOOL		m_Result;
};
class CPDF_RenderStatus : public CFX_Object
{
public:
    CPDF_RenderStatus();
    ~CPDF_RenderStatus();
    FX_BOOL			Initialize(int level, class CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, const CFX_AffineMatrix* pDeviceMatrix,
                               const CPDF_PageObject* pStopObj, const CPDF_RenderStatus* pParentStatus,
                               const CPDF_GraphicStates* pInitialStates, const CPDF_RenderOptions* pOptions,
                               int transparency, FX_BOOL bDropObjects, CPDF_Dictionary* pFormResource = NULL,
                               FX_BOOL bStdCS = FALSE,	CPDF_Type3Char* pType3Char = NULL, FX_ARGB fill_color = 0,
                               FX_DWORD GroupFamily = 0, FX_BOOL bLoadMask = FALSE);
    void			RenderObjectList(const CPDF_PageObjects* pObjs, const CFX_AffineMatrix* pObj2Device);
    void			RenderSingleObject(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device);
    FX_BOOL			ContinueSingleObject(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, IFX_Pause* pPause);
    CPDF_RenderOptions	m_Options;
    CPDF_Dictionary*    m_pFormResource;
    CPDF_Dictionary*    m_pPageResource;
    CFX_PtrArray		m_Type3FontCache;
    CPDF_RenderContext* GetContext()
    {
        return m_pContext;
    }
protected:
    friend class	CPDF_ImageRenderer;
    friend class	CPDF_RenderContext;
    void			ProcessClipPath(CPDF_ClipPath ClipPath, const CFX_AffineMatrix* pObj2Device);
    void			DrawClipPath(CPDF_ClipPath ClipPath, const CFX_AffineMatrix* pObj2Device);
    FX_BOOL			ProcessTransparency(const CPDF_PageObject* PageObj, const CFX_AffineMatrix* pObj2Device);
    void			ProcessObjectNoClip(const CPDF_PageObject* PageObj, const CFX_AffineMatrix* pObj2Device);
    void			DrawObjWithBackground(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device);
    FX_BOOL         DrawObjWithBlend(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device);
    FX_BOOL			ProcessPath(CPDF_PathObject* pPathObj, const CFX_AffineMatrix* pObj2Device);
    void			ProcessPathPattern(CPDF_PathObject* pPathObj, const CFX_AffineMatrix* pObj2Device, int& filltype, FX_BOOL& bStroke);
    void			DrawPathWithPattern(CPDF_PathObject* pPathObj, const CFX_AffineMatrix* pObj2Device, CPDF_Color* pColor, FX_BOOL bStroke);
    void			DrawTilingPattern(CPDF_TilingPattern* pPattern, CPDF_PageObject* pPageObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStroke);
    void			DrawShadingPattern(CPDF_ShadingPattern* pPattern, CPDF_PageObject* pPageObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStroke);
    FX_BOOL			SelectClipPath(CPDF_PathObject* pPathObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStroke);
    FX_BOOL			ProcessImage(CPDF_ImageObject* pImageObj, const CFX_AffineMatrix* pObj2Device);
    FX_BOOL			OutputBitmapAlpha(CPDF_ImageObject* pImageObj, const CFX_AffineMatrix* pImage2Device);
    FX_BOOL			OutputImage(CPDF_ImageObject* pImageObj, const CFX_AffineMatrix* pImage2Device);
    FX_BOOL			OutputDIBSource(const CFX_DIBSource* pOutputBitmap, FX_ARGB fill_argb, int bitmap_alpha,
                                    const CFX_AffineMatrix* pImage2Device, CPDF_ImageCache* pImageCache, FX_DWORD flags);
    void			CompositeDIBitmap(CFX_DIBitmap* pDIBitmap, int left, int top, FX_ARGB mask_argb,
                                      int bitmap_alpha, int blend_mode, int bIsolated);
    FX_BOOL			ProcessInlines(CPDF_InlineImages* pInlines, const CFX_AffineMatrix* pObj2Device);
    FX_BOOL			ProcessShading(CPDF_ShadingObject* pShadingObj, const CFX_AffineMatrix* pObj2Device);
    void			DrawShading(CPDF_ShadingPattern* pPattern, CFX_AffineMatrix* pMatrix, FX_RECT& clip_rect,
                                int alpha, FX_BOOL bAlphaMode);
    FX_BOOL			ProcessType3Text(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device);
    FX_BOOL			ProcessText(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device, CFX_PathData* pClippingPath);
    void			DrawTextPathWithPattern(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device,
                                            CPDF_Font* pFont, FX_FLOAT font_size,
                                            const CFX_AffineMatrix* pTextMatrix, FX_BOOL bFill, FX_BOOL bStroke);
    FX_BOOL			ProcessForm(CPDF_FormObject* pFormObj, const CFX_AffineMatrix* pObj2Device);
    CFX_DIBitmap*	GetBackdrop(const CPDF_PageObject* pObj, const FX_RECT& rect, int& left, int& top,
                                FX_BOOL bBackAlphaRequired);
    CFX_DIBitmap*	LoadSMask(CPDF_Dictionary* pSMaskDict, FX_RECT* pClipRect, const CFX_AffineMatrix* pMatrix);
    void			Init(CPDF_RenderContext* pParent);
    static class CPDF_Type3Cache*	GetCachedType3(CPDF_Type3Font* pFont);
    static CPDF_GraphicStates* CloneObjStates(const CPDF_GraphicStates* pPathObj, FX_BOOL bStroke);
    CPDF_TransferFunc*	GetTransferFunc(CPDF_Object* pObject) const;
    FX_ARGB			GetFillArgb(const CPDF_PageObject* pObj, FX_BOOL bType3 = FALSE) const;
    FX_ARGB			GetStrokeArgb(const CPDF_PageObject* pObj) const;
    CPDF_RenderContext*		m_pContext;
    FX_BOOL					m_bStopped;
    void			DitherObjectArea(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device);
    FX_BOOL			GetObjectClippedRect(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bLogical, FX_RECT &rect) const;
    void			GetScaledMatrix(CFX_Matrix &matrix) const;
protected:
    int						m_Level;
    CFX_RenderDevice*		m_pDevice;
    CFX_AffineMatrix		m_DeviceMatrix;
    CPDF_ClipPath			m_LastClipPath;
    const CPDF_PageObject*	m_pCurObj;
    const CPDF_PageObject*	m_pStopObj;
    CPDF_GraphicStates		m_InitialStates;
    int						m_HalftoneLimit;
    IPDF_ObjectRenderer*	m_pObjectRenderer;
    FX_BOOL					m_bPrint;
    int						m_Transparency;
    int						m_DitherBits;
    FX_BOOL					m_bDropObjects;
    FX_BOOL					m_bStdCS;
    FX_DWORD                m_GroupFamily;
    FX_BOOL                 m_bLoadMask;
    CPDF_Type3Char *        m_pType3Char;
    FX_ARGB					m_T3FillColor;
    int                     m_curBlend;
};
class CPDF_ImageLoader : public CFX_Object
{
public:
    CPDF_ImageLoader()
    {
        m_pBitmap = NULL;
        m_pMask = NULL;
        m_MatteColor = 0;
        m_bCached = FALSE;
        m_nDownsampleWidth = 0;
        m_nDownsampleHeight = 0;
    }

    FX_BOOL					Load(const CPDF_ImageObject* pImage, CPDF_PageRenderCache* pCache, FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0, FX_BOOL bLoadMask = FALSE, CPDF_RenderStatus* pRenderStatus = NULL);

    FX_BOOL					StartLoadImage(const CPDF_ImageObject* pImage, CPDF_PageRenderCache* pCache, FX_LPVOID& LoadHandle, FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0, FX_BOOL bLoadMask = FALSE, CPDF_RenderStatus* pRenderStatus = NULL, FX_INT32 nDownsampleWidth = 0, FX_INT32 nDownsampleHeight = 0);
    FX_BOOL					Continue(FX_LPVOID LoadHandle, IFX_Pause* pPause);
    ~CPDF_ImageLoader();
    CFX_DIBSource*			m_pBitmap;
    CFX_DIBSource*			m_pMask;
    FX_DWORD				m_MatteColor;
    FX_BOOL					m_bCached;
protected:
    FX_INT32                m_nDownsampleWidth;
    FX_INT32                m_nDownsampleHeight;
};
class CPDF_ProgressiveImageLoaderHandle : public CFX_Object
{
public:
    CPDF_ProgressiveImageLoaderHandle();
    ~CPDF_ProgressiveImageLoaderHandle();

    FX_BOOL			Start(CPDF_ImageLoader* pImageLoader, const CPDF_ImageObject* pImage, CPDF_PageRenderCache* pCache, FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0, FX_BOOL bLoadMask = FALSE, CPDF_RenderStatus* pRenderStatus = NULL, FX_INT32 nDownsampleWidth = 0, FX_INT32 nDownsampleHeight = 0);
    FX_BOOL			Continue(IFX_Pause* pPause);
protected:
    CPDF_ImageLoader*	m_pImageLoader;
    CPDF_PageRenderCache* m_pCache;
    CPDF_ImageObject* m_pImage;
    FX_INT32            m_nDownsampleWidth;
    FX_INT32            m_nDownsampleHeight;
};
class CFX_ImageTransformer;
class CPDF_ImageRenderer : public IPDF_ObjectRenderer
{
public:
    CPDF_ImageRenderer();
    ~CPDF_ImageRenderer();
    FX_BOOL		Start(CPDF_RenderStatus* pStatus, const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStdCS, int blendType = FXDIB_BLEND_NORMAL);
    FX_BOOL		Start(CPDF_RenderStatus* pStatus, const CFX_DIBSource* pDIBSource, FX_ARGB bitmap_argb,
                      int bitmap_alpha, const CFX_AffineMatrix* pImage2Device, FX_DWORD flags, FX_BOOL bStdCS, int blendType = FXDIB_BLEND_NORMAL);
    FX_BOOL		Continue(IFX_Pause* pPause);
protected:
    CPDF_RenderStatus*	m_pRenderStatus;
    CPDF_ImageObject*	m_pImageObject;
    int					m_Status;
    const CFX_AffineMatrix* m_pObj2Device;
    CFX_AffineMatrix	m_ImageMatrix;
    CPDF_ImageLoader	m_Loader;
    const CFX_DIBSource*		m_pDIBSource;
    CFX_DIBitmap*		m_pClone;
    int					m_BitmapAlpha;
    FX_BOOL				m_bPatternColor;
    CPDF_Pattern*		m_pPattern;
    FX_ARGB				m_FillArgb;
    FX_DWORD			m_Flags;
    CPDF_QuickStretcher*	m_pQuickStretcher;
    CFX_ImageTransformer*	m_pTransformer;
    CPDF_ImageRenderer*	m_pRenderer2;
    FX_LPVOID			m_DeviceHandle;
    FX_LPVOID           m_LoadHandle;
    FX_BOOL				m_bStdCS;
    int					m_BlendType;
    FX_BOOL				StartBitmapAlpha();
    FX_BOOL				StartDIBSource();
    FX_BOOL				StartRenderDIBSource();
    FX_BOOL				StartLoadDIBSource();
    FX_BOOL				DrawMaskedImage();
    FX_BOOL				DrawPatternImage(const CFX_Matrix* pObj2Device);
};
class CPDF_ScaledRenderBuffer : public CFX_Object
{
public:
    CPDF_ScaledRenderBuffer();
    ~CPDF_ScaledRenderBuffer();
    FX_BOOL				Initialize(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, FX_RECT* pRect,
                                   const CPDF_PageObject* pObj, const CPDF_RenderOptions *pOptions = NULL, int max_dpi = 0);
    CFX_RenderDevice*	GetDevice()
    {
        return m_pBitmapDevice ? m_pBitmapDevice : m_pDevice;
    }
    CFX_AffineMatrix*	GetMatrix()
    {
        return &m_Matrix;
    }
    void				OutputToDevice();
private:
    CFX_RenderDevice*	m_pDevice;
    CPDF_RenderContext*	m_pContext;
    FX_RECT				m_Rect;
    const CPDF_PageObject* m_pObject;
    CFX_FxgeDevice*	m_pBitmapDevice;
    CFX_AffineMatrix	m_Matrix;
};
class ICodec_ScanlineDecoder;
class CPDF_QuickStretcher : public CFX_Object
{
public:
    CPDF_QuickStretcher();
    ~CPDF_QuickStretcher();
    FX_BOOL		Start(CPDF_ImageObject* pImageObj, CFX_AffineMatrix* pImage2Device, const FX_RECT* pClipBox);
    FX_BOOL		Continue(IFX_Pause* pPause);
    CFX_DIBitmap*	m_pBitmap;
    int			m_ResultLeft, m_ResultTop, m_ClipLeft, m_ClipTop;
    int			m_DestWidth, m_DestHeight, m_ResultWidth, m_ResultHeight;
    int			m_Bpp, m_SrcWidth, m_SrcHeight;
    FX_BOOL		m_bFlipX, m_bFlipY;
    CPDF_ColorSpace*	m_pCS;
    ICodec_ScanlineDecoder*	m_pDecoder;
    CPDF_StreamAcc m_StreamAcc;
    int			m_LineIndex;
};
class CPDF_DeviceBuffer : public CFX_Object
{
public:
    CPDF_DeviceBuffer();
    ~CPDF_DeviceBuffer();
    FX_BOOL				Initialize(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, FX_RECT* pRect,
                                   const CPDF_PageObject* pObj, int max_dpi = 0);
    void				OutputToDevice();
    CFX_DIBitmap*		GetBitmap() const
    {
        return m_pBitmap;
    }
    const CFX_AffineMatrix*	GetMatrix() const
    {
        return &m_Matrix;
    }
private:
    CFX_RenderDevice*	m_pDevice;
    CPDF_RenderContext*	m_pContext;
    FX_RECT				m_Rect;
    const CPDF_PageObject* m_pObject;
    CFX_DIBitmap*		m_pBitmap;
    CFX_AffineMatrix	m_Matrix;
};
class CPDF_ImageCache : public CFX_Object
{
public:
    CPDF_ImageCache(CPDF_Document* pDoc, CPDF_Stream* pStream);
    ~CPDF_ImageCache();
    void				ClearImageData();
    void				Reset(const CFX_DIBitmap* pBitmap);
    FX_BOOL				GetCachedBitmap(CFX_DIBSource*& pBitmap, CFX_DIBSource*& pMask, FX_DWORD& MatteColor, CPDF_Dictionary* pPageResources,
                                        FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0, FX_BOOL bLoadMask = FALSE,
                                        CPDF_RenderStatus* pRenderStatus = NULL, FX_INT32 downsampleWidth = 0, FX_INT32 downsampleHeight = 0);
    FX_DWORD			EstimateSize() const
    {
        return m_dwCacheSize;
    }
    FX_DWORD			GetTimeCount() const
    {
        return m_dwTimeCount;
    }
    CPDF_Stream*		GetStream() const
    {
        return m_pStream;
    }
    void				SetTimeCount(FX_DWORD dwTimeCount)
    {
        m_dwTimeCount = dwTimeCount;
    }
    int					m_dwTimeCount;
public:
    int					StartGetCachedBitmap(CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources,
            FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0,
            FX_BOOL bLoadMask = FALSE, CPDF_RenderStatus* pRenderStatus = NULL, FX_INT32 downsampleWidth = 0, FX_INT32 downsampleHeight = 0);
    int					Continue(IFX_Pause* pPause);
    int 				ContinueGetCachedBitmap();
    CFX_DIBSource*		DetachBitmap();
    CFX_DIBSource*		DetachMask();
    CFX_DIBSource*		m_pCurBitmap;
    CFX_DIBSource*		m_pCurMask;
    FX_DWORD			m_MatteColor;
    CPDF_RenderStatus*  m_pRenderStatus;
protected:
    CPDF_Document*		m_pDocument;
    CPDF_Stream*		m_pStream;
    CFX_DIBSource*		m_pCachedBitmap;
    CFX_DIBSource*		m_pCachedMask;
    FX_DWORD			m_dwCacheSize;
    void	CalcSize();
};
typedef struct {
    FX_FLOAT			m_DecodeMin;
    FX_FLOAT			m_DecodeStep;
    int					m_ColorKeyMin;
    int					m_ColorKeyMax;
} DIB_COMP_DATA;
class CPDF_DIBSource : public CFX_DIBSource
{
public:
    CPDF_DIBSource();
    virtual ~CPDF_DIBSource();
    FX_BOOL				Load(CPDF_Document* pDoc, const CPDF_Stream* pStream,
                             CPDF_DIBSource** ppMask, FX_DWORD* pMatteColor,
                             CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources,
                             FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0, FX_BOOL bLoadMask = FALSE);
    virtual FX_BOOL		SkipToScanline(int line, IFX_Pause* pPause) const;
    virtual	FX_LPBYTE	GetBuffer() const;
    virtual FX_LPCBYTE	GetScanline(int line) const;
    virtual void		DownSampleScanline(int line, FX_LPBYTE dest_scan, int dest_bpp,
                                           int dest_width, FX_BOOL bFlipX, int clip_left, int clip_width) const;
    virtual void		SetDownSampleSize(int dest_width, int dest_height) const;
    CFX_DIBitmap*		GetBitmap() const;
    void				ReleaseBitmap(CFX_DIBitmap*) const;
    void				ClearImageData();
public:
    int					StartLoadDIBSource(CPDF_Document* pDoc, const CPDF_Stream* pStream, FX_BOOL bHasMask,
                                           CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources,
                                           FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0, FX_BOOL bLoadMask = FALSE);
    int					ContinueLoadDIBSource(IFX_Pause* pPause);
    int					StratLoadMask();
    int					StartLoadMaskDIB();
    int					ContinueLoadMaskDIB(IFX_Pause* pPause);
    int					ContinueToLoadMask();
    CPDF_DIBSource*		DetachMask();
    CPDF_DIBSource*		m_pMask;
    FX_DWORD			m_MatteColor;
    FX_LPVOID			m_pJbig2Context;
    CPDF_StreamAcc*		m_pGlobalStream;
    FX_BOOL				m_bStdCS;
    int					m_Status;
    CPDF_Object*		m_pMaskStream;
    FX_BOOL				m_bHasMask;
protected:
    FX_BOOL				LoadColorInfo(CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources);
    DIB_COMP_DATA*      GetDecodeAndMaskArray(FX_BOOL& bDefaultDecode, FX_BOOL& bColorKey);
    CPDF_DIBSource*		LoadMask(FX_DWORD& MatteColor);
    CPDF_DIBSource*		LoadMaskDIB(CPDF_Stream* pMask);
    void				LoadJpxBitmap();
    void				LoadJbig2Bitmap();
    void				LoadPalette();
    FX_BOOL				CreateDecoder();
    void				TranslateScanline24bpp(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan) const;
    void                ValidateDictParam();
    CPDF_Document*		m_pDocument;
    const CPDF_Stream*	m_pStream;
    CPDF_StreamAcc*		m_pStreamAcc;
    const CPDF_Dictionary*	m_pDict;
    CPDF_ColorSpace*	m_pColorSpace;
    FX_DWORD			m_Family, m_bpc, m_bpc_orig, m_nComponents, m_GroupFamily;
    FX_BOOL				m_bLoadMask;
    FX_BOOL				m_bDefaultDecode, m_bImageMask, m_bColorKey;
    DIB_COMP_DATA*		m_pCompData;
    FX_LPBYTE			m_pLineBuf;
    FX_LPBYTE			m_pMaskedLine;
    CFX_DIBitmap*		m_pCachedBitmap;
    ICodec_ScanlineDecoder*	m_pDecoder;
};
#ifdef _FPDFAPI_MINI_
#define FPDF_HUGE_IMAGE_SIZE	3000000
#else
#define FPDF_HUGE_IMAGE_SIZE	60000000
#endif
class CPDF_DIBTransferFunc : public CFX_FilteredDIB
{
public:
    CPDF_DIBTransferFunc(const CPDF_TransferFunc* pTransferFunc);
    virtual FXDIB_Format	GetDestFormat();
    virtual FX_ARGB*		GetDestPalette()
    {
        return NULL;
    }
    virtual void			TranslateScanline(FX_LPBYTE dest_buf, FX_LPCBYTE src_buf) const;
    virtual void			TranslateDownSamples(FX_LPBYTE dest_buf, FX_LPCBYTE src_buf, int pixels, int Bpp) const;
    FX_LPCBYTE				m_RampR;
    FX_LPCBYTE				m_RampG;
    FX_LPCBYTE				m_RampB;
};
struct _CPDF_UniqueKeyGen {
    void		Generate(int count, ...);
    FX_CHAR		m_Key[128];
    int			m_KeyLen;
};
