blob: d70ecf1a6e16c70d455a20d634706a461fc58de7 [file] [log] [blame]
// 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_FPDFAPI_PAGE_PAGEINT_H_
#define CORE_FPDFAPI_PAGE_PAGEINT_H_
#include <map>
#include <memory>
#include <set>
#include <unordered_map>
#include <vector>
#include "core/fpdfapi/page/cpdf_contentmark.h"
#include "core/fpdfapi/page/cpdf_countedobject.h"
#include "core/fpdfapi/page/cpdf_pageobjectholder.h"
#include "core/fpdfapi/page/cpdf_streamcontentparser.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fxcrt/cfx_string_pool_template.h"
#include "core/fxcrt/cfx_weak_ptr.h"
#include "core/fxge/cfx_pathdata.h"
#include "core/fxge/cfx_renderdevice.h"
class CPDF_AllStates;
class CPDF_ColorSpace;
class CPDF_ExpIntFunc;
class CPDF_Font;
class CPDF_FontEncoding;
class CPDF_Form;
class CPDF_IccProfile;
class CPDF_Image;
class CPDF_ImageObject;
class CPDF_Page;
class CPDF_Pattern;
class CPDF_SampledFunc;
class CPDF_StitchFunc;
class CPDF_StreamAcc;
class CPDF_TextObject;
class CPDF_Type3Char;
#define PARSE_STEP_LIMIT 100
class CPDF_StreamParser {
public:
enum SyntaxType { EndOfData, Number, Keyword, Name, Others };
CPDF_StreamParser(const uint8_t* pData, uint32_t dwSize);
CPDF_StreamParser(const uint8_t* pData,
uint32_t dwSize,
const CFX_WeakPtr<CFX_ByteStringPool>& pPool);
~CPDF_StreamParser();
CPDF_Stream* ReadInlineStream(CPDF_Document* pDoc,
CPDF_Dictionary* pDict,
CPDF_Object* pCSObj);
SyntaxType ParseNextElement();
uint8_t* GetWordBuf() { return m_WordBuffer; }
uint32_t GetWordSize() const { return m_WordSize; }
CPDF_Object* GetObject();
uint32_t GetPos() const { return m_Pos; }
void SetPos(uint32_t pos) { m_Pos = pos; }
CPDF_Object* ReadNextObject(bool bAllowNestedArray, uint32_t dwInArrayLevel);
private:
friend class fpdf_page_parser_old_ReadHexString_Test;
void GetNextWord(bool& bIsNumber);
CFX_ByteString ReadString();
CFX_ByteString ReadHexString();
bool PositionIsInBounds() const;
const uint8_t* m_pBuf;
uint32_t m_Size; // Length in bytes of m_pBuf.
uint32_t m_Pos; // Current byte position within m_pBuf.
uint8_t m_WordBuffer[256];
uint32_t m_WordSize;
CPDF_Object* m_pLastObj;
CFX_WeakPtr<CFX_ByteStringPool> m_pPool;
};
#define _FPDF_MAX_TYPE3_FORM_LEVEL_ 4
class CPDF_ContentParser {
public:
enum ParseStatus { Ready, ToBeContinued, Done };
CPDF_ContentParser();
~CPDF_ContentParser();
ParseStatus GetStatus() const { return m_Status; }
void Start(CPDF_Page* pPage);
void Start(CPDF_Form* pForm,
CPDF_AllStates* pGraphicStates,
const CFX_Matrix* pParentMatrix,
CPDF_Type3Char* pType3Char,
int level);
void Continue(IFX_Pause* pPause);
private:
enum InternalStage {
STAGE_GETCONTENT = 1,
STAGE_PARSE,
STAGE_CHECKCLIP,
};
ParseStatus m_Status;
InternalStage m_InternalStage;
CPDF_PageObjectHolder* m_pObjectHolder;
bool m_bForm;
CPDF_Type3Char* m_pType3Char;
uint32_t m_nStreams;
std::unique_ptr<CPDF_StreamAcc> m_pSingleStream;
std::vector<std::unique_ptr<CPDF_StreamAcc>> m_StreamArray;
uint8_t* m_pData;
uint32_t m_Size;
uint32_t m_CurrentOffset;
std::unique_ptr<CPDF_StreamContentParser> m_pParser;
};
class CPDF_Function {
public:
enum class Type {
kTypeInvalid = -1,
kType0Sampled = 0,
kType2ExpotentialInterpolation = 2,
kType3Stitching = 3,
kType4PostScript = 4,
};
static std::unique_ptr<CPDF_Function> Load(CPDF_Object* pFuncObj);
static Type IntegerToFunctionType(int iType);
virtual ~CPDF_Function();
FX_BOOL Call(FX_FLOAT* inputs,
uint32_t ninputs,
FX_FLOAT* results,
int& nresults) const;
uint32_t CountInputs() const { return m_nInputs; }
uint32_t CountOutputs() const { return m_nOutputs; }
FX_FLOAT GetDomain(int i) const { return m_pDomains[i]; }
FX_FLOAT GetRange(int i) const { return m_pRanges[i]; }
const CPDF_SampledFunc* ToSampledFunc() const;
const CPDF_ExpIntFunc* ToExpIntFunc() const;
const CPDF_StitchFunc* ToStitchFunc() const;
protected:
explicit CPDF_Function(Type type);
FX_BOOL Init(CPDF_Object* pObj);
virtual FX_BOOL v_Init(CPDF_Object* pObj) = 0;
virtual FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const = 0;
uint32_t m_nInputs;
uint32_t m_nOutputs;
FX_FLOAT* m_pDomains;
FX_FLOAT* m_pRanges;
const Type m_Type;
};
class CPDF_ExpIntFunc : public CPDF_Function {
public:
CPDF_ExpIntFunc();
~CPDF_ExpIntFunc() override;
// CPDF_Function
FX_BOOL v_Init(CPDF_Object* pObj) override;
FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override;
uint32_t m_nOrigOutputs;
FX_FLOAT m_Exponent;
FX_FLOAT* m_pBeginValues;
FX_FLOAT* m_pEndValues;
};
class CPDF_SampledFunc : public CPDF_Function {
public:
struct SampleEncodeInfo {
FX_FLOAT encode_max;
FX_FLOAT encode_min;
uint32_t sizes;
};
struct SampleDecodeInfo {
FX_FLOAT decode_max;
FX_FLOAT decode_min;
};
CPDF_SampledFunc();
~CPDF_SampledFunc() override;
// CPDF_Function
FX_BOOL v_Init(CPDF_Object* pObj) override;
FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override;
const std::vector<SampleEncodeInfo>& GetEncodeInfo() const {
return m_EncodeInfo;
}
uint32_t GetBitsPerSample() const { return m_nBitsPerSample; }
const CPDF_StreamAcc* GetSampleStream() const {
return m_pSampleStream.get();
}
private:
std::vector<SampleEncodeInfo> m_EncodeInfo;
std::vector<SampleDecodeInfo> m_DecodeInfo;
uint32_t m_nBitsPerSample;
uint32_t m_SampleMax;
std::unique_ptr<CPDF_StreamAcc> m_pSampleStream;
};
class CPDF_StitchFunc : public CPDF_Function {
public:
CPDF_StitchFunc();
~CPDF_StitchFunc() override;
// CPDF_Function
FX_BOOL v_Init(CPDF_Object* pObj) override;
FX_BOOL v_Call(FX_FLOAT* inputs, FX_FLOAT* results) const override;
const std::vector<std::unique_ptr<CPDF_Function>>& GetSubFunctions() const {
return m_pSubFunctions;
}
FX_FLOAT GetBound(size_t i) const { return m_pBounds[i]; }
private:
std::vector<std::unique_ptr<CPDF_Function>> m_pSubFunctions;
FX_FLOAT* m_pBounds;
FX_FLOAT* m_pEncode;
static const uint32_t kRequiredNumInputs = 1;
};
class CPDF_IccProfile {
public:
CPDF_IccProfile(const uint8_t* pData, uint32_t dwSize);
~CPDF_IccProfile();
uint32_t GetComponents() const { return m_nSrcComponents; }
bool m_bsRGB;
void* m_pTransform;
private:
uint32_t m_nSrcComponents;
};
class CPDF_DeviceCS : public CPDF_ColorSpace {
public:
CPDF_DeviceCS(CPDF_Document* pDoc, int family);
FX_BOOL GetRGB(FX_FLOAT* pBuf,
FX_FLOAT& R,
FX_FLOAT& G,
FX_FLOAT& B) const override;
FX_BOOL SetRGB(FX_FLOAT* pBuf,
FX_FLOAT R,
FX_FLOAT G,
FX_FLOAT B) const override;
FX_BOOL v_GetCMYK(FX_FLOAT* pBuf,
FX_FLOAT& c,
FX_FLOAT& m,
FX_FLOAT& y,
FX_FLOAT& k) const override;
FX_BOOL v_SetCMYK(FX_FLOAT* pBuf,
FX_FLOAT c,
FX_FLOAT m,
FX_FLOAT y,
FX_FLOAT k) const override;
void TranslateImageLine(uint8_t* pDestBuf,
const uint8_t* pSrcBuf,
int pixels,
int image_width,
int image_height,
FX_BOOL bTransMask = FALSE) const override;
};
class CPDF_PatternCS : public CPDF_ColorSpace {
public:
explicit CPDF_PatternCS(CPDF_Document* pDoc);
~CPDF_PatternCS() override;
FX_BOOL v_Load(CPDF_Document* pDoc, CPDF_Array* pArray) override;
FX_BOOL GetRGB(FX_FLOAT* pBuf,
FX_FLOAT& R,
FX_FLOAT& G,
FX_FLOAT& B) const override;
CPDF_ColorSpace* GetBaseCS() const override;
private:
CPDF_ColorSpace* m_pBaseCS;
CPDF_CountedColorSpace* m_pCountedBaseCS;
};
#define MAX_PATTERN_COLORCOMPS 16
struct PatternValue {
CPDF_Pattern* m_pPattern;
CPDF_CountedPattern* m_pCountedPattern;
int m_nComps;
FX_FLOAT m_Comps[MAX_PATTERN_COLORCOMPS];
};
CFX_ByteStringC PDF_FindKeyAbbreviationForTesting(const CFX_ByteStringC& abbr);
CFX_ByteStringC PDF_FindValueAbbreviationForTesting(
const CFX_ByteStringC& abbr);
void PDF_ReplaceAbbr(CPDF_Object* pObj);
#endif // CORE_FPDFAPI_PAGE_PAGEINT_H_