| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "../../../include/fpdfapi/fpdf_page.h" | 7 #include "../../../include/fpdfapi/fpdf_page.h" |
| 8 #include "../../../include/fpdfapi/fpdf_module.h" | 8 #include "../../../include/fpdfapi/fpdf_module.h" |
| 9 #include "../../../include/fxcodec/fx_codec.h" | 9 #include "../../../include/fxcodec/fx_codec.h" |
| 10 #include "pageint.h" | 10 #include "pageint.h" |
| 11 #include <limits.h> | 11 #include <limits.h> |
| 12 const FX_CHAR* const _PDF_OpCharType = | 12 const FX_CHAR* const _PDF_OpCharType = |
| 13 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" | 13 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" |
| 14 "IIVIIIIVIIVIIIIIVVIIIIIIIIIIIIII" | 14 "IIVIIIIVIIVIIIIIVVIIIIIIIIIIIIII" |
| 15 "IIVVVVVVIVVVVVVIVVVVVIIVVIIIIIII" | 15 "IIVVVVVVIVVVVVVIVVVVVIIVVIIIIIII" |
| 16 "IIVVVVVVVVVVVVVVIVVVIIVVIVVIIIII" | 16 "IIVVVVVVVVVVVVVVIVVVIIVVIVVIIIII" |
| 17 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" | 17 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" |
| 18 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" | 18 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" |
| 19 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" | 19 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII" |
| 20 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII"; | 20 "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII"; |
| 21 FX_BOOL _PDF_HasInvalidOpChar(const FX_CHAR* op) | 21 FX_BOOL _PDF_HasInvalidOpChar(const FX_CHAR* op) { |
| 22 { | 22 if (!op) { |
| 23 if(!op) { | |
| 24 return FALSE; | |
| 25 } | |
| 26 uint8_t ch; | |
| 27 while((ch = *op++)) { | |
| 28 if(_PDF_OpCharType[ch] == 'I') { | |
| 29 return TRUE; | |
| 30 } | |
| 31 } | |
| 32 return FALSE; | 23 return FALSE; |
| 24 } |
| 25 uint8_t ch; |
| 26 while ((ch = *op++)) { |
| 27 if (_PDF_OpCharType[ch] == 'I') { |
| 28 return TRUE; |
| 29 } |
| 30 } |
| 31 return FALSE; |
| 33 } | 32 } |
| 34 class CPDF_StreamParserAutoClearer { | 33 class CPDF_StreamParserAutoClearer { |
| 35 public: | 34 public: |
| 36 CPDF_StreamParserAutoClearer(CPDF_StreamParser** scoped_variable, CPDF_Strea
mParser* new_parser) | 35 CPDF_StreamParserAutoClearer(CPDF_StreamParser** scoped_variable, |
| 37 : scoped_variable_(scoped_variable) { | 36 CPDF_StreamParser* new_parser) |
| 38 *scoped_variable_ = new_parser; | 37 : scoped_variable_(scoped_variable) { |
| 39 } | 38 *scoped_variable_ = new_parser; |
| 40 ~CPDF_StreamParserAutoClearer() { *scoped_variable_ = NULL; } | 39 } |
| 41 private: | 40 ~CPDF_StreamParserAutoClearer() { *scoped_variable_ = NULL; } |
| 42 CPDF_StreamParser** scoped_variable_; | 41 |
| 42 private: |
| 43 CPDF_StreamParser** scoped_variable_; |
| 43 }; | 44 }; |
| 44 FX_DWORD CPDF_StreamContentParser::Parse(const uint8_t* pData, FX_DWORD dwSize,
FX_DWORD max_cost) | 45 FX_DWORD CPDF_StreamContentParser::Parse(const uint8_t* pData, |
| 45 { | 46 FX_DWORD dwSize, |
| 46 if (m_Level > _FPDF_MAX_FORM_LEVEL_) { | 47 FX_DWORD max_cost) { |
| 47 return dwSize; | 48 if (m_Level > _FPDF_MAX_FORM_LEVEL_) { |
| 48 } | 49 return dwSize; |
| 49 FX_DWORD InitObjCount = m_pObjectList->CountObjects(); | 50 } |
| 50 CPDF_StreamParser syntax(pData, dwSize); | 51 FX_DWORD InitObjCount = m_pObjectList->CountObjects(); |
| 51 CPDF_StreamParserAutoClearer auto_clearer(&m_pSyntax, &syntax); | 52 CPDF_StreamParser syntax(pData, dwSize); |
| 52 m_CompatCount = 0; | 53 CPDF_StreamParserAutoClearer auto_clearer(&m_pSyntax, &syntax); |
| 53 while (1) { | 54 m_CompatCount = 0; |
| 54 FX_DWORD cost = m_pObjectList->CountObjects() - InitObjCount; | 55 while (1) { |
| 55 if (max_cost && cost >= max_cost) { | 56 FX_DWORD cost = m_pObjectList->CountObjects() - InitObjCount; |
| 56 break; | 57 if (max_cost && cost >= max_cost) { |
| 57 } | 58 break; |
| 58 switch (syntax.ParseNextElement()) { | 59 } |
| 59 case CPDF_StreamParser::EndOfData: | 60 switch (syntax.ParseNextElement()) { |
| 60 return m_pSyntax->GetPos(); | 61 case CPDF_StreamParser::EndOfData: |
| 61 case CPDF_StreamParser::Keyword: | 62 return m_pSyntax->GetPos(); |
| 62 if(!OnOperator((char*)syntax.GetWordBuf()) && _PDF_HasInvalidOpC
har((char*)syntax.GetWordBuf())) { | 63 case CPDF_StreamParser::Keyword: |
| 63 m_bAbort = TRUE; | 64 if (!OnOperator((char*)syntax.GetWordBuf()) && |
| 64 } | 65 _PDF_HasInvalidOpChar((char*)syntax.GetWordBuf())) { |
| 65 if (m_bAbort) { | 66 m_bAbort = TRUE; |
| 66 return m_pSyntax->GetPos(); | 67 } |
| 67 } | 68 if (m_bAbort) { |
| 68 ClearAllParams(); | 69 return m_pSyntax->GetPos(); |
| 69 break; | 70 } |
| 70 case CPDF_StreamParser::Number: | 71 ClearAllParams(); |
| 71 AddNumberParam((char*)syntax.GetWordBuf(), syntax.GetWordSize())
; | 72 break; |
| 72 break; | 73 case CPDF_StreamParser::Number: |
| 73 case CPDF_StreamParser::Name: | 74 AddNumberParam((char*)syntax.GetWordBuf(), syntax.GetWordSize()); |
| 74 AddNameParam((const FX_CHAR*)syntax.GetWordBuf() + 1, syntax.Get
WordSize() - 1); | 75 break; |
| 75 break; | 76 case CPDF_StreamParser::Name: |
| 77 AddNameParam((const FX_CHAR*)syntax.GetWordBuf() + 1, |
| 78 syntax.GetWordSize() - 1); |
| 79 break; |
| 80 default: |
| 81 AddObjectParam(syntax.GetObject()); |
| 82 } |
| 83 } |
| 84 return m_pSyntax->GetPos(); |
| 85 } |
| 86 void _PDF_ReplaceAbbr(CPDF_Object* pObj); |
| 87 void CPDF_StreamContentParser::Handle_BeginImage() { |
| 88 FX_FILESIZE savePos = m_pSyntax->GetPos(); |
| 89 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); |
| 90 while (1) { |
| 91 CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); |
| 92 if (type == CPDF_StreamParser::Keyword) { |
| 93 CFX_ByteString bsKeyword(m_pSyntax->GetWordBuf(), |
| 94 m_pSyntax->GetWordSize()); |
| 95 if (bsKeyword != FX_BSTRC("ID")) { |
| 96 m_pSyntax->SetPos(savePos); |
| 97 pDict->Release(); |
| 98 return; |
| 99 } |
| 100 } |
| 101 if (type != CPDF_StreamParser::Name) { |
| 102 break; |
| 103 } |
| 104 CFX_ByteString key((const FX_CHAR*)m_pSyntax->GetWordBuf() + 1, |
| 105 m_pSyntax->GetWordSize() - 1); |
| 106 CPDF_Object* pObj = m_pSyntax->ReadNextObject(); |
| 107 if (!key.IsEmpty()) { |
| 108 pDict->SetAt(key, pObj, m_pDocument); |
| 109 } else if (pObj) { |
| 110 pObj->Release(); |
| 111 } |
| 112 } |
| 113 _PDF_ReplaceAbbr(pDict); |
| 114 CPDF_Object* pCSObj = NULL; |
| 115 if (pDict->KeyExist(FX_BSTRC("ColorSpace"))) { |
| 116 pCSObj = pDict->GetElementValue(FX_BSTRC("ColorSpace")); |
| 117 if (pCSObj->GetType() == PDFOBJ_NAME) { |
| 118 CFX_ByteString name = pCSObj->GetString(); |
| 119 if (name != FX_BSTRC("DeviceRGB") && name != FX_BSTRC("DeviceGray") && |
| 120 name != FX_BSTRC("DeviceCMYK")) { |
| 121 pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name); |
| 122 if (pCSObj && !pCSObj->GetObjNum()) { |
| 123 pCSObj = pCSObj->Clone(); |
| 124 pDict->SetAt(FX_BSTRC("ColorSpace"), pCSObj, m_pDocument); |
| 125 } |
| 126 } |
| 127 } |
| 128 } |
| 129 CPDF_Stream* pStream = m_pSyntax->ReadInlineStream( |
| 130 m_pDocument, pDict, pCSObj, m_Options.m_bDecodeInlineImage); |
| 131 while (1) { |
| 132 CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); |
| 133 if (type == CPDF_StreamParser::EndOfData) { |
| 134 break; |
| 135 } |
| 136 if (type != CPDF_StreamParser::Keyword) { |
| 137 continue; |
| 138 } |
| 139 if (m_pSyntax->GetWordSize() == 2 && m_pSyntax->GetWordBuf()[0] == 'E' && |
| 140 m_pSyntax->GetWordBuf()[1] == 'I') { |
| 141 break; |
| 142 } |
| 143 } |
| 144 if (m_Options.m_bTextOnly) { |
| 145 if (pStream) { |
| 146 pStream->Release(); |
| 147 } else { |
| 148 pDict->Release(); |
| 149 } |
| 150 return; |
| 151 } |
| 152 pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Image")); |
| 153 CPDF_ImageObject* pImgObj = AddImage(pStream, NULL, TRUE); |
| 154 if (!pImgObj) { |
| 155 if (pStream) { |
| 156 pStream->Release(); |
| 157 } else { |
| 158 pDict->Release(); |
| 159 } |
| 160 } |
| 161 } |
| 162 void CPDF_StreamContentParser::ParsePathObject() { |
| 163 FX_FLOAT params[6] = {}; |
| 164 int nParams = 0; |
| 165 int last_pos = m_pSyntax->GetPos(); |
| 166 while (1) { |
| 167 CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); |
| 168 FX_BOOL bProcessed = TRUE; |
| 169 switch (type) { |
| 170 case CPDF_StreamParser::EndOfData: |
| 171 return; |
| 172 case CPDF_StreamParser::Keyword: { |
| 173 int len = m_pSyntax->GetWordSize(); |
| 174 if (len == 1) { |
| 175 switch (m_pSyntax->GetWordBuf()[0]) { |
| 176 case 'm': |
| 177 AddPathPoint(params[0], params[1], FXPT_MOVETO); |
| 178 nParams = 0; |
| 179 break; |
| 180 case 'l': |
| 181 AddPathPoint(params[0], params[1], FXPT_LINETO); |
| 182 nParams = 0; |
| 183 break; |
| 184 case 'c': |
| 185 AddPathPoint(params[0], params[1], FXPT_BEZIERTO); |
| 186 AddPathPoint(params[2], params[3], FXPT_BEZIERTO); |
| 187 AddPathPoint(params[4], params[5], FXPT_BEZIERTO); |
| 188 nParams = 0; |
| 189 break; |
| 190 case 'v': |
| 191 AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXPT_BEZIERTO); |
| 192 AddPathPoint(params[0], params[1], FXPT_BEZIERTO); |
| 193 AddPathPoint(params[2], params[3], FXPT_BEZIERTO); |
| 194 nParams = 0; |
| 195 break; |
| 196 case 'y': |
| 197 AddPathPoint(params[0], params[1], FXPT_BEZIERTO); |
| 198 AddPathPoint(params[2], params[3], FXPT_BEZIERTO); |
| 199 AddPathPoint(params[2], params[3], FXPT_BEZIERTO); |
| 200 nParams = 0; |
| 201 break; |
| 202 case 'h': |
| 203 Handle_ClosePath(); |
| 204 nParams = 0; |
| 205 break; |
| 76 default: | 206 default: |
| 77 AddObjectParam(syntax.GetObject()); | 207 bProcessed = FALSE; |
| 78 } | 208 break; |
| 79 } | 209 } |
| 80 return m_pSyntax->GetPos(); | 210 } else if (len == 2) { |
| 81 } | 211 if (m_pSyntax->GetWordBuf()[0] == 'r' && |
| 82 void _PDF_ReplaceAbbr(CPDF_Object* pObj); | 212 m_pSyntax->GetWordBuf()[1] == 'e') { |
| 83 void CPDF_StreamContentParser::Handle_BeginImage() | 213 AddPathRect(params[0], params[1], params[2], params[3]); |
| 84 { | 214 nParams = 0; |
| 85 FX_FILESIZE savePos = m_pSyntax->GetPos(); | 215 } else { |
| 86 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); | 216 bProcessed = FALSE; |
| 87 while (1) { | 217 } |
| 88 CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); | |
| 89 if (type == CPDF_StreamParser::Keyword) { | |
| 90 CFX_ByteString bsKeyword(m_pSyntax->GetWordBuf(), m_pSyntax->GetWord
Size()); | |
| 91 if (bsKeyword != FX_BSTRC("ID")) { | |
| 92 m_pSyntax->SetPos(savePos); | |
| 93 pDict->Release(); | |
| 94 return; | |
| 95 } | |
| 96 } | |
| 97 if (type != CPDF_StreamParser::Name) { | |
| 98 break; | |
| 99 } | |
| 100 CFX_ByteString key((const FX_CHAR*)m_pSyntax->GetWordBuf() + 1, m_pSynta
x->GetWordSize() - 1); | |
| 101 CPDF_Object* pObj = m_pSyntax->ReadNextObject(); | |
| 102 if (!key.IsEmpty()) { | |
| 103 pDict->SetAt(key, pObj, m_pDocument); | |
| 104 } else if (pObj) { | |
| 105 pObj->Release(); | |
| 106 } | |
| 107 } | |
| 108 _PDF_ReplaceAbbr(pDict); | |
| 109 CPDF_Object* pCSObj = NULL; | |
| 110 if (pDict->KeyExist(FX_BSTRC("ColorSpace"))) { | |
| 111 pCSObj = pDict->GetElementValue(FX_BSTRC("ColorSpace")); | |
| 112 if (pCSObj->GetType() == PDFOBJ_NAME) { | |
| 113 CFX_ByteString name = pCSObj->GetString(); | |
| 114 if (name != FX_BSTRC("DeviceRGB") && name != FX_BSTRC("DeviceGray")
&& name != FX_BSTRC("DeviceCMYK")) { | |
| 115 pCSObj = FindResourceObj(FX_BSTRC("ColorSpace"), name); | |
| 116 if (pCSObj && !pCSObj->GetObjNum()) { | |
| 117 pCSObj = pCSObj->Clone(); | |
| 118 pDict->SetAt(FX_BSTRC("ColorSpace"), pCSObj, m_pDocument); | |
| 119 } | |
| 120 } | |
| 121 } | |
| 122 } | |
| 123 CPDF_Stream* pStream = m_pSyntax->ReadInlineStream(m_pDocument, pDict, pCSOb
j, m_Options.m_bDecodeInlineImage); | |
| 124 while (1) { | |
| 125 CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); | |
| 126 if (type == CPDF_StreamParser::EndOfData) { | |
| 127 break; | |
| 128 } | |
| 129 if (type != CPDF_StreamParser::Keyword) { | |
| 130 continue; | |
| 131 } | |
| 132 if (m_pSyntax->GetWordSize() == 2 && m_pSyntax->GetWordBuf()[0] == 'E' &
& | |
| 133 m_pSyntax->GetWordBuf()[1] == 'I') { | |
| 134 break; | |
| 135 } | |
| 136 } | |
| 137 if (m_Options.m_bTextOnly) { | |
| 138 if (pStream) { | |
| 139 pStream->Release(); | |
| 140 } else { | 218 } else { |
| 141 pDict->Release(); | 219 bProcessed = FALSE; |
| 142 } | 220 } |
| 143 return; | 221 if (bProcessed) { |
| 144 } | 222 last_pos = m_pSyntax->GetPos(); |
| 145 pDict->SetAtName(FX_BSTRC("Subtype"), FX_BSTRC("Image")); | 223 } |
| 146 CPDF_ImageObject *pImgObj = AddImage(pStream, NULL, TRUE); | 224 break; |
| 147 if (!pImgObj) { | 225 } |
| 148 if (pStream) { | 226 case CPDF_StreamParser::Number: { |
| 149 pStream->Release(); | 227 if (nParams == 6) { |
| 150 } else { | 228 break; |
| 151 pDict->Release(); | 229 } |
| 152 } | 230 FX_BOOL bInteger; |
| 153 } | 231 int value; |
| 154 } | 232 FX_atonum( |
| 155 void CPDF_StreamContentParser::ParsePathObject() | 233 CFX_ByteStringC(m_pSyntax->GetWordBuf(), m_pSyntax->GetWordSize()), |
| 156 { | 234 bInteger, &value); |
| 157 FX_FLOAT params[6] = {}; | 235 params[nParams++] = bInteger ? (FX_FLOAT)value : *(FX_FLOAT*)&value; |
| 158 int nParams = 0; | 236 break; |
| 159 int last_pos = m_pSyntax->GetPos(); | 237 } |
| 160 while (1) { | 238 default: |
| 161 CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); | 239 bProcessed = FALSE; |
| 162 FX_BOOL bProcessed = TRUE; | 240 } |
| 163 switch (type) { | 241 if (!bProcessed) { |
| 164 case CPDF_StreamParser::EndOfData: | 242 m_pSyntax->SetPos(last_pos); |
| 165 return; | 243 return; |
| 166 case CPDF_StreamParser::Keyword: { | 244 } |
| 167 int len = m_pSyntax->GetWordSize(); | 245 } |
| 168 if (len == 1) { | 246 } |
| 169 switch (m_pSyntax->GetWordBuf()[0]) { | 247 CPDF_StreamParser::CPDF_StreamParser(const uint8_t* pData, FX_DWORD dwSize) { |
| 170 case 'm': | 248 m_pBuf = pData; |
| 171 AddPathPoint(params[0], params[1], FXPT_MOVETO); | 249 m_Size = dwSize; |
| 172 nParams = 0; | 250 m_Pos = 0; |
| 173 break; | 251 m_pLastObj = NULL; |
| 174 case 'l': | 252 } |
| 175 AddPathPoint(params[0], params[1], FXPT_LINETO); | 253 CPDF_StreamParser::~CPDF_StreamParser() { |
| 176 nParams = 0; | 254 if (m_pLastObj) { |
| 177 break; | 255 m_pLastObj->Release(); |
| 178 case 'c': | 256 } |
| 179 AddPathPoint(params[0], params[1], FXPT_BEZIERTO
); | 257 } |
| 180 AddPathPoint(params[2], params[3], FXPT_BEZIERTO
); | 258 FX_DWORD _DecodeAllScanlines(ICodec_ScanlineDecoder* pDecoder, |
| 181 AddPathPoint(params[4], params[5], FXPT_BEZIERTO
); | 259 uint8_t*& dest_buf, |
| 182 nParams = 0; | 260 FX_DWORD& dest_size) { |
| 183 break; | 261 if (pDecoder == NULL) { |
| 184 case 'v': | 262 return (FX_DWORD)-1; |
| 185 AddPathPoint(m_PathCurrentX, m_PathCurrentY, FXP
T_BEZIERTO); | 263 } |
| 186 AddPathPoint(params[0], params[1], FXPT_BEZIERTO
); | 264 int ncomps = pDecoder->CountComps(); |
| 187 AddPathPoint(params[2], params[3], FXPT_BEZIERTO
); | 265 int bpc = pDecoder->GetBPC(); |
| 188 nParams = 0; | 266 int width = pDecoder->GetWidth(); |
| 189 break; | 267 int height = pDecoder->GetHeight(); |
| 190 case 'y': | 268 int pitch = (width * ncomps * bpc + 7) / 8; |
| 191 AddPathPoint(params[0], params[1], FXPT_BEZIERTO
); | 269 if (height == 0 || pitch > (1 << 30) / height) { |
| 192 AddPathPoint(params[2], params[3], FXPT_BEZIERTO
); | |
| 193 AddPathPoint(params[2], params[3], FXPT_BEZIERTO
); | |
| 194 nParams = 0; | |
| 195 break; | |
| 196 case 'h': | |
| 197 Handle_ClosePath(); | |
| 198 nParams = 0; | |
| 199 break; | |
| 200 default: | |
| 201 bProcessed = FALSE; | |
| 202 break; | |
| 203 } | |
| 204 } else if (len == 2) { | |
| 205 if (m_pSyntax->GetWordBuf()[0] == 'r' && m_pSyntax->GetW
ordBuf()[1] == 'e') { | |
| 206 AddPathRect(params[0], params[1], params[2], params[
3]); | |
| 207 nParams = 0; | |
| 208 } else { | |
| 209 bProcessed = FALSE; | |
| 210 } | |
| 211 } else { | |
| 212 bProcessed = FALSE; | |
| 213 } | |
| 214 if (bProcessed) { | |
| 215 last_pos = m_pSyntax->GetPos(); | |
| 216 } | |
| 217 break; | |
| 218 } | |
| 219 case CPDF_StreamParser::Number: { | |
| 220 if (nParams == 6) { | |
| 221 break; | |
| 222 } | |
| 223 FX_BOOL bInteger; | |
| 224 int value; | |
| 225 FX_atonum(CFX_ByteStringC(m_pSyntax->GetWordBuf(), m_pSyntax
->GetWordSize()), bInteger, &value); | |
| 226 params[nParams++] = bInteger ? (FX_FLOAT)value : *(FX_FLOAT*
)&value; | |
| 227 break; | |
| 228 } | |
| 229 default: | |
| 230 bProcessed = FALSE; | |
| 231 } | |
| 232 if (!bProcessed) { | |
| 233 m_pSyntax->SetPos(last_pos); | |
| 234 return; | |
| 235 } | |
| 236 } | |
| 237 } | |
| 238 CPDF_StreamParser::CPDF_StreamParser(const uint8_t* pData, FX_DWORD dwSize) | |
| 239 { | |
| 240 m_pBuf = pData; | |
| 241 m_Size = dwSize; | |
| 242 m_Pos = 0; | |
| 243 m_pLastObj = NULL; | |
| 244 } | |
| 245 CPDF_StreamParser::~CPDF_StreamParser() | |
| 246 { | |
| 247 if (m_pLastObj) { | |
| 248 m_pLastObj->Release(); | |
| 249 } | |
| 250 } | |
| 251 FX_DWORD _DecodeAllScanlines(ICodec_ScanlineDecoder* pDecoder, uint8_t*& dest_bu
f, FX_DWORD& dest_size) | |
| 252 { | |
| 253 if (pDecoder == NULL) { | |
| 254 return (FX_DWORD) - 1; | |
| 255 } | |
| 256 int ncomps = pDecoder->CountComps(); | |
| 257 int bpc = pDecoder->GetBPC(); | |
| 258 int width = pDecoder->GetWidth(); | |
| 259 int height = pDecoder->GetHeight(); | |
| 260 int pitch = (width * ncomps * bpc + 7) / 8; | |
| 261 if (height == 0 || pitch > (1 << 30) / height) { | |
| 262 delete pDecoder; | |
| 263 return -1; | |
| 264 } | |
| 265 dest_buf = FX_Alloc2D(uint8_t, pitch, height); | |
| 266 dest_size = pitch * height; // Safe since checked alloc returned. | |
| 267 for (int row = 0; row < height; row ++) { | |
| 268 uint8_t* pLine = pDecoder->GetScanline(row); | |
| 269 if (pLine == NULL) { | |
| 270 break; | |
| 271 } | |
| 272 FXSYS_memcpy(dest_buf + row * pitch, pLine, pitch); | |
| 273 } | |
| 274 FX_DWORD srcoff = pDecoder->GetSrcOffset(); | |
| 275 delete pDecoder; | 270 delete pDecoder; |
| 276 return srcoff; | 271 return -1; |
| 277 } | 272 } |
| 278 ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder(const uint8_t* src_buf, FX_DWOR
D src_size, int width, int height, | 273 dest_buf = FX_Alloc2D(uint8_t, pitch, height); |
| 279 const CPDF_Dictionary* pParams); | 274 dest_size = pitch * height; // Safe since checked alloc returned. |
| 280 FX_DWORD _A85Decode(const uint8_t* src_buf, FX_DWORD src_size, uint8_t*& dest_bu
f, FX_DWORD& dest_size); | 275 for (int row = 0; row < height; row++) { |
| 281 FX_DWORD _HexDecode(const uint8_t* src_buf, FX_DWORD src_size, uint8_t*& dest_bu
f, FX_DWORD& dest_size); | 276 uint8_t* pLine = pDecoder->GetScanline(row); |
| 282 FX_DWORD FPDFAPI_FlateOrLZWDecode(FX_BOOL bLZW, const uint8_t* src_buf, FX_DWORD
src_size, CPDF_Dictionary* pParams, | 277 if (pLine == NULL) { |
| 283 FX_DWORD estimated_size, uint8_t*& dest_buf, F
X_DWORD& dest_size); | 278 break; |
| 284 FX_DWORD PDF_DecodeInlineStream(const uint8_t* src_buf, FX_DWORD limit, | 279 } |
| 285 int width, int height, CFX_ByteString& decoder, | 280 FXSYS_memcpy(dest_buf + row * pitch, pLine, pitch); |
| 286 CPDF_Dictionary* pParam, uint8_t*& dest_buf, FX_
DWORD& dest_size) | 281 } |
| 287 { | 282 FX_DWORD srcoff = pDecoder->GetSrcOffset(); |
| 288 if (decoder == FX_BSTRC("CCITTFaxDecode") || decoder == FX_BSTRC("CCF")) { | 283 delete pDecoder; |
| 289 ICodec_ScanlineDecoder* pDecoder = FPDFAPI_CreateFaxDecoder(src_buf, lim
it, width, height, pParam); | 284 return srcoff; |
| 290 return _DecodeAllScanlines(pDecoder, dest_buf, dest_size); | 285 } |
| 291 } | 286 ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder( |
| 292 if (decoder == FX_BSTRC("ASCII85Decode") || decoder == FX_BSTRC("A85")) { | 287 const uint8_t* src_buf, |
| 293 return _A85Decode(src_buf, limit, dest_buf, dest_size); | 288 FX_DWORD src_size, |
| 294 } | 289 int width, |
| 295 if (decoder == FX_BSTRC("ASCIIHexDecode") || decoder == FX_BSTRC("AHx")) { | 290 int height, |
| 296 return _HexDecode(src_buf, limit, dest_buf, dest_size); | 291 const CPDF_Dictionary* pParams); |
| 297 } | 292 FX_DWORD _A85Decode(const uint8_t* src_buf, |
| 298 if (decoder == FX_BSTRC("FlateDecode") || decoder == FX_BSTRC("Fl")) { | 293 FX_DWORD src_size, |
| 299 return FPDFAPI_FlateOrLZWDecode(FALSE, src_buf, limit, pParam, dest_size
, dest_buf, dest_size); | 294 uint8_t*& dest_buf, |
| 300 } | 295 FX_DWORD& dest_size); |
| 301 if (decoder == FX_BSTRC("LZWDecode") || decoder == FX_BSTRC("LZW")) { | 296 FX_DWORD _HexDecode(const uint8_t* src_buf, |
| 302 return FPDFAPI_FlateOrLZWDecode(TRUE, src_buf, limit, pParam, 0, dest_bu
f, dest_size); | 297 FX_DWORD src_size, |
| 303 } | 298 uint8_t*& dest_buf, |
| 304 if (decoder == FX_BSTRC("DCTDecode") || decoder == FX_BSTRC("DCT")) { | 299 FX_DWORD& dest_size); |
| 305 ICodec_ScanlineDecoder* pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule(
)->CreateDecoder( | 300 FX_DWORD FPDFAPI_FlateOrLZWDecode(FX_BOOL bLZW, |
| 306 src_buf, limit, width, height, 0, pParam ? pParam->GetInteger(FX_BST
RC("ColorTransform"), 1) : 1); | 301 const uint8_t* src_buf, |
| 307 return _DecodeAllScanlines(pDecoder, dest_buf, dest_size); | 302 FX_DWORD src_size, |
| 308 } | 303 CPDF_Dictionary* pParams, |
| 309 if (decoder == FX_BSTRC("RunLengthDecode") || decoder == FX_BSTRC("RL")) { | 304 FX_DWORD estimated_size, |
| 310 return RunLengthDecode(src_buf, limit, dest_buf, dest_size); | 305 uint8_t*& dest_buf, |
| 311 } | 306 FX_DWORD& dest_size); |
| 312 dest_size = 0; | 307 FX_DWORD PDF_DecodeInlineStream(const uint8_t* src_buf, |
| 313 dest_buf = 0; | 308 FX_DWORD limit, |
| 314 return (FX_DWORD) - 1; | 309 int width, |
| 315 } | 310 int height, |
| 316 CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc, CPDF_Dicti
onary* pDict, CPDF_Object* pCSObj, FX_BOOL bDecode) | 311 CFX_ByteString& decoder, |
| 317 { | 312 CPDF_Dictionary* pParam, |
| 318 if (m_Pos == m_Size) { | 313 uint8_t*& dest_buf, |
| 319 return NULL; | 314 FX_DWORD& dest_size) { |
| 320 } | 315 if (decoder == FX_BSTRC("CCITTFaxDecode") || decoder == FX_BSTRC("CCF")) { |
| 321 if (PDF_CharType[m_pBuf[m_Pos]] == 'W') { | 316 ICodec_ScanlineDecoder* pDecoder = |
| 322 m_Pos ++; | 317 FPDFAPI_CreateFaxDecoder(src_buf, limit, width, height, pParam); |
| 323 } | 318 return _DecodeAllScanlines(pDecoder, dest_buf, dest_size); |
| 324 CFX_ByteString Decoder; | 319 } |
| 325 CPDF_Dictionary* pParam = NULL; | 320 if (decoder == FX_BSTRC("ASCII85Decode") || decoder == FX_BSTRC("A85")) { |
| 326 CPDF_Object* pFilter = pDict->GetElementValue(FX_BSTRC("Filter")); | 321 return _A85Decode(src_buf, limit, dest_buf, dest_size); |
| 327 if (pFilter == NULL) { | 322 } |
| 328 } else if (pFilter->GetType() == PDFOBJ_ARRAY) { | 323 if (decoder == FX_BSTRC("ASCIIHexDecode") || decoder == FX_BSTRC("AHx")) { |
| 329 Decoder = ((CPDF_Array*)pFilter)->GetString(0); | 324 return _HexDecode(src_buf, limit, dest_buf, dest_size); |
| 325 } |
| 326 if (decoder == FX_BSTRC("FlateDecode") || decoder == FX_BSTRC("Fl")) { |
| 327 return FPDFAPI_FlateOrLZWDecode(FALSE, src_buf, limit, pParam, dest_size, |
| 328 dest_buf, dest_size); |
| 329 } |
| 330 if (decoder == FX_BSTRC("LZWDecode") || decoder == FX_BSTRC("LZW")) { |
| 331 return FPDFAPI_FlateOrLZWDecode(TRUE, src_buf, limit, pParam, 0, dest_buf, |
| 332 dest_size); |
| 333 } |
| 334 if (decoder == FX_BSTRC("DCTDecode") || decoder == FX_BSTRC("DCT")) { |
| 335 ICodec_ScanlineDecoder* pDecoder = |
| 336 CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder( |
| 337 src_buf, limit, width, height, 0, |
| 338 pParam ? pParam->GetInteger(FX_BSTRC("ColorTransform"), 1) : 1); |
| 339 return _DecodeAllScanlines(pDecoder, dest_buf, dest_size); |
| 340 } |
| 341 if (decoder == FX_BSTRC("RunLengthDecode") || decoder == FX_BSTRC("RL")) { |
| 342 return RunLengthDecode(src_buf, limit, dest_buf, dest_size); |
| 343 } |
| 344 dest_size = 0; |
| 345 dest_buf = 0; |
| 346 return (FX_DWORD)-1; |
| 347 } |
| 348 CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc, |
| 349 CPDF_Dictionary* pDict, |
| 350 CPDF_Object* pCSObj, |
| 351 FX_BOOL bDecode) { |
| 352 if (m_Pos == m_Size) { |
| 353 return NULL; |
| 354 } |
| 355 if (PDF_CharType[m_pBuf[m_Pos]] == 'W') { |
| 356 m_Pos++; |
| 357 } |
| 358 CFX_ByteString Decoder; |
| 359 CPDF_Dictionary* pParam = NULL; |
| 360 CPDF_Object* pFilter = pDict->GetElementValue(FX_BSTRC("Filter")); |
| 361 if (pFilter == NULL) { |
| 362 } else if (pFilter->GetType() == PDFOBJ_ARRAY) { |
| 363 Decoder = ((CPDF_Array*)pFilter)->GetString(0); |
| 364 CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms")); |
| 365 if (pParams) { |
| 366 pParam = pParams->GetDict(0); |
| 367 } |
| 368 } else { |
| 369 Decoder = pFilter->GetString(); |
| 370 pParam = pDict->GetDict(FX_BSTRC("DecodeParms")); |
| 371 } |
| 372 FX_DWORD width = pDict->GetInteger(FX_BSTRC("Width")); |
| 373 FX_DWORD height = pDict->GetInteger(FX_BSTRC("Height")); |
| 374 FX_DWORD OrigSize = 0; |
| 375 if (pCSObj != NULL) { |
| 376 FX_DWORD bpc = pDict->GetInteger(FX_BSTRC("BitsPerComponent")); |
| 377 FX_DWORD nComponents = 1; |
| 378 CPDF_ColorSpace* pCS = pDoc->LoadColorSpace(pCSObj); |
| 379 if (pCS == NULL) { |
| 380 nComponents = 3; |
| 381 } else { |
| 382 nComponents = pCS->CountComponents(); |
| 383 pDoc->GetPageData()->ReleaseColorSpace(pCSObj); |
| 384 } |
| 385 FX_DWORD pitch = width; |
| 386 if (bpc && pitch > INT_MAX / bpc) { |
| 387 return NULL; |
| 388 } |
| 389 pitch *= bpc; |
| 390 if (nComponents && pitch > INT_MAX / nComponents) { |
| 391 return NULL; |
| 392 } |
| 393 pitch *= nComponents; |
| 394 if (pitch > INT_MAX - 7) { |
| 395 return NULL; |
| 396 } |
| 397 pitch += 7; |
| 398 pitch /= 8; |
| 399 OrigSize = pitch; |
| 400 } else { |
| 401 if (width > INT_MAX - 7) { |
| 402 return NULL; |
| 403 } |
| 404 OrigSize = ((width + 7) / 8); |
| 405 } |
| 406 if (height && OrigSize > INT_MAX / height) { |
| 407 return NULL; |
| 408 } |
| 409 OrigSize *= height; |
| 410 uint8_t* pData = NULL; |
| 411 FX_DWORD dwStreamSize; |
| 412 if (Decoder.IsEmpty()) { |
| 413 if (OrigSize > m_Size - m_Pos) { |
| 414 OrigSize = m_Size - m_Pos; |
| 415 } |
| 416 pData = FX_Alloc(uint8_t, OrigSize); |
| 417 FXSYS_memcpy(pData, m_pBuf + m_Pos, OrigSize); |
| 418 dwStreamSize = OrigSize; |
| 419 m_Pos += OrigSize; |
| 420 } else { |
| 421 FX_DWORD dwDestSize = OrigSize; |
| 422 dwStreamSize = |
| 423 PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, width, height, |
| 424 Decoder, pParam, pData, dwDestSize); |
| 425 if ((int)dwStreamSize < 0) { |
| 426 return NULL; |
| 427 } |
| 428 if (bDecode) { |
| 429 m_Pos += dwStreamSize; |
| 430 dwStreamSize = dwDestSize; |
| 431 if (pFilter->GetType() == PDFOBJ_ARRAY) { |
| 432 ((CPDF_Array*)pFilter)->RemoveAt(0); |
| 330 CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms")); | 433 CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms")); |
| 331 if (pParams) { | 434 if (pParams) { |
| 332 pParam = pParams->GetDict(0); | 435 pParams->RemoveAt(0); |
| 333 } | 436 } |
| 437 } else { |
| 438 pDict->RemoveAt(FX_BSTRC("Filter")); |
| 439 pDict->RemoveAt(FX_BSTRC("DecodeParms")); |
| 440 } |
| 334 } else { | 441 } else { |
| 335 Decoder = pFilter->GetString(); | 442 if (pData) { |
| 336 pParam = pDict->GetDict(FX_BSTRC("DecodeParms")); | 443 FX_Free(pData); |
| 337 } | 444 } |
| 338 FX_DWORD width = pDict->GetInteger(FX_BSTRC("Width")); | 445 FX_DWORD dwSavePos = m_Pos; |
| 339 FX_DWORD height = pDict->GetInteger(FX_BSTRC("Height")); | 446 m_Pos += dwStreamSize; |
| 340 FX_DWORD OrigSize = 0; | 447 while (1) { |
| 341 if (pCSObj != NULL) { | 448 FX_DWORD dwPrevPos = m_Pos; |
| 342 FX_DWORD bpc = pDict->GetInteger(FX_BSTRC("BitsPerComponent")); | 449 CPDF_StreamParser::SyntaxType type = ParseNextElement(); |
| 343 FX_DWORD nComponents = 1; | 450 if (type == CPDF_StreamParser::EndOfData) { |
| 344 CPDF_ColorSpace* pCS = pDoc->LoadColorSpace(pCSObj); | 451 break; |
| 345 if (pCS == NULL) { | 452 } |
| 346 nComponents = 3; | 453 if (type != CPDF_StreamParser::Keyword) { |
| 347 } else { | 454 dwStreamSize += m_Pos - dwPrevPos; |
| 348 nComponents = pCS->CountComponents(); | 455 continue; |
| 349 pDoc->GetPageData()->ReleaseColorSpace(pCSObj); | 456 } |
| 350 } | 457 if (GetWordSize() == 2 && GetWordBuf()[0] == 'E' && |
| 351 FX_DWORD pitch = width; | 458 GetWordBuf()[1] == 'I') { |
| 352 if (bpc && pitch > INT_MAX / bpc) { | 459 m_Pos = dwPrevPos; |
| 353 return NULL; | 460 break; |
| 354 } | 461 } |
| 355 pitch *= bpc; | 462 dwStreamSize += m_Pos - dwPrevPos; |
| 356 if (nComponents && pitch > INT_MAX / nComponents) { | 463 } |
| 357 return NULL; | 464 m_Pos = dwSavePos; |
| 358 } | 465 pData = FX_Alloc(uint8_t, dwStreamSize); |
| 359 pitch *= nComponents; | 466 FXSYS_memcpy(pData, m_pBuf + m_Pos, dwStreamSize); |
| 360 if (pitch > INT_MAX - 7) { | 467 m_Pos += dwStreamSize; |
| 361 return NULL; | 468 } |
| 362 } | 469 } |
| 363 pitch += 7; | 470 pDict->SetAtInteger(FX_BSTRC("Length"), (int)dwStreamSize); |
| 364 pitch /= 8; | 471 return CPDF_Stream::Create(pData, dwStreamSize, pDict); |
| 365 OrigSize = pitch; | |
| 366 } else { | |
| 367 if (width > INT_MAX - 7) { | |
| 368 return NULL; | |
| 369 } | |
| 370 OrigSize = ((width + 7) / 8); | |
| 371 } | |
| 372 if (height && OrigSize > INT_MAX / height) { | |
| 373 return NULL; | |
| 374 } | |
| 375 OrigSize *= height; | |
| 376 uint8_t* pData = NULL; | |
| 377 FX_DWORD dwStreamSize; | |
| 378 if (Decoder.IsEmpty()) { | |
| 379 if (OrigSize > m_Size - m_Pos) { | |
| 380 OrigSize = m_Size - m_Pos; | |
| 381 } | |
| 382 pData = FX_Alloc(uint8_t, OrigSize); | |
| 383 FXSYS_memcpy(pData, m_pBuf + m_Pos, OrigSize); | |
| 384 dwStreamSize = OrigSize; | |
| 385 m_Pos += OrigSize; | |
| 386 } else { | |
| 387 FX_DWORD dwDestSize = OrigSize; | |
| 388 dwStreamSize = PDF_DecodeInlineStream(m_pBuf + m_Pos, m_Size - m_Pos, wi
dth, height, Decoder, pParam, | |
| 389 pData, dwDestSize); | |
| 390 if ((int)dwStreamSize < 0) { | |
| 391 return NULL; | |
| 392 } | |
| 393 if (bDecode) { | |
| 394 m_Pos += dwStreamSize; | |
| 395 dwStreamSize = dwDestSize; | |
| 396 if (pFilter->GetType() == PDFOBJ_ARRAY) { | |
| 397 ((CPDF_Array*)pFilter)->RemoveAt(0); | |
| 398 CPDF_Array* pParams = pDict->GetArray(FX_BSTRC("DecodeParms")); | |
| 399 if (pParams) { | |
| 400 pParams->RemoveAt(0); | |
| 401 } | |
| 402 } else { | |
| 403 pDict->RemoveAt(FX_BSTRC("Filter")); | |
| 404 pDict->RemoveAt(FX_BSTRC("DecodeParms")); | |
| 405 } | |
| 406 } else { | |
| 407 if (pData) { | |
| 408 FX_Free(pData); | |
| 409 } | |
| 410 FX_DWORD dwSavePos = m_Pos; | |
| 411 m_Pos += dwStreamSize; | |
| 412 while (1) { | |
| 413 FX_DWORD dwPrevPos = m_Pos; | |
| 414 CPDF_StreamParser::SyntaxType type = ParseNextElement(); | |
| 415 if (type == CPDF_StreamParser::EndOfData) { | |
| 416 break; | |
| 417 } | |
| 418 if (type != CPDF_StreamParser::Keyword) { | |
| 419 dwStreamSize += m_Pos - dwPrevPos; | |
| 420 continue; | |
| 421 } | |
| 422 if (GetWordSize() == 2 && GetWordBuf()[0] == 'E' && | |
| 423 GetWordBuf()[1] == 'I') { | |
| 424 m_Pos = dwPrevPos; | |
| 425 break; | |
| 426 } | |
| 427 dwStreamSize += m_Pos - dwPrevPos; | |
| 428 } | |
| 429 m_Pos = dwSavePos; | |
| 430 pData = FX_Alloc(uint8_t, dwStreamSize); | |
| 431 FXSYS_memcpy(pData, m_pBuf + m_Pos, dwStreamSize); | |
| 432 m_Pos += dwStreamSize; | |
| 433 } | |
| 434 } | |
| 435 pDict->SetAtInteger(FX_BSTRC("Length"), (int)dwStreamSize); | |
| 436 return CPDF_Stream::Create(pData, dwStreamSize, pDict); | |
| 437 } | 472 } |
| 438 #define MAX_WORD_BUFFER 256 | 473 #define MAX_WORD_BUFFER 256 |
| 439 #define MAX_STRING_LENGTH» 32767 | 474 #define MAX_STRING_LENGTH 32767 |
| 440 #define FXDWORD_TRUE FXDWORD_FROM_LSBFIRST(0x65757274) | 475 #define FXDWORD_TRUE FXDWORD_FROM_LSBFIRST(0x65757274) |
| 441 #define FXDWORD_NULL FXDWORD_FROM_LSBFIRST(0x6c6c756e) | 476 #define FXDWORD_NULL FXDWORD_FROM_LSBFIRST(0x6c6c756e) |
| 442 #define FXDWORD_FALS FXDWORD_FROM_LSBFIRST(0x736c6166) | 477 #define FXDWORD_FALS FXDWORD_FROM_LSBFIRST(0x736c6166) |
| 443 CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() | 478 CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() { |
| 444 { | 479 if (m_pLastObj) { |
| 445 if (m_pLastObj) { | 480 m_pLastObj->Release(); |
| 446 m_pLastObj->Release(); | 481 m_pLastObj = NULL; |
| 447 m_pLastObj = NULL; | 482 } |
| 448 } | 483 m_WordSize = 0; |
| 449 m_WordSize = 0; | 484 FX_BOOL bIsNumber = TRUE; |
| 450 FX_BOOL bIsNumber = TRUE; | 485 if (m_Pos >= m_Size) { |
| 451 if (m_Pos >= m_Size) { | 486 return EndOfData; |
| 487 } |
| 488 int ch = m_pBuf[m_Pos++]; |
| 489 int type = PDF_CharType[ch]; |
| 490 while (1) { |
| 491 while (type == 'W') { |
| 492 if (m_Size <= m_Pos) { |
| 452 return EndOfData; | 493 return EndOfData; |
| 453 } | 494 } |
| 454 int ch = m_pBuf[m_Pos++]; | 495 ch = m_pBuf[m_Pos++]; |
| 455 int type = PDF_CharType[ch]; | 496 type = PDF_CharType[ch]; |
| 497 } |
| 498 if (ch != '%') { |
| 499 break; |
| 500 } |
| 456 while (1) { | 501 while (1) { |
| 457 while (type == 'W') { | 502 if (m_Size <= m_Pos) { |
| 458 if (m_Size <= m_Pos) { | 503 return EndOfData; |
| 459 return EndOfData; | 504 } |
| 460 } | 505 ch = m_pBuf[m_Pos++]; |
| 461 ch = m_pBuf[m_Pos++]; | 506 if (ch == '\r' || ch == '\n') { |
| 462 type = PDF_CharType[ch]; | 507 break; |
| 463 } | 508 } |
| 464 if (ch != '%') { | 509 } |
| 465 break; | 510 type = PDF_CharType[ch]; |
| 466 } | 511 } |
| 467 while (1) { | 512 if (type == 'D' && ch != '/') { |
| 468 if (m_Size <= m_Pos) { | 513 m_Pos--; |
| 469 return EndOfData; | 514 m_pLastObj = ReadNextObject(); |
| 470 } | 515 return Others; |
| 471 ch = m_pBuf[m_Pos++]; | 516 } |
| 472 if (ch == '\r' || ch == '\n') { | 517 while (1) { |
| 473 break; | 518 if (m_WordSize < MAX_WORD_BUFFER) { |
| 474 } | 519 m_WordBuffer[m_WordSize++] = ch; |
| 475 } | 520 } |
| 476 type = PDF_CharType[ch]; | 521 if (type != 'N') { |
| 477 } | 522 bIsNumber = FALSE; |
| 478 if (type == 'D' && ch != '/') { | 523 } |
| 479 m_Pos --; | 524 if (m_Size <= m_Pos) { |
| 480 m_pLastObj = ReadNextObject(); | 525 break; |
| 481 return Others; | 526 } |
| 527 ch = m_pBuf[m_Pos++]; |
| 528 type = PDF_CharType[ch]; |
| 529 if (type == 'D' || type == 'W') { |
| 530 m_Pos--; |
| 531 break; |
| 532 } |
| 533 } |
| 534 m_WordBuffer[m_WordSize] = 0; |
| 535 if (bIsNumber) { |
| 536 return Number; |
| 537 } |
| 538 if (m_WordBuffer[0] == '/') { |
| 539 return Name; |
| 540 } |
| 541 if (m_WordSize == 4) { |
| 542 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) { |
| 543 m_pLastObj = CPDF_Boolean::Create(TRUE); |
| 544 return Others; |
| 545 } |
| 546 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) { |
| 547 m_pLastObj = CPDF_Null::Create(); |
| 548 return Others; |
| 549 } |
| 550 } else if (m_WordSize == 5) { |
| 551 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e') { |
| 552 m_pLastObj = CPDF_Boolean::Create(FALSE); |
| 553 return Others; |
| 554 } |
| 555 } |
| 556 return Keyword; |
| 557 } |
| 558 void CPDF_StreamParser::SkipPathObject() { |
| 559 FX_DWORD command_startpos = m_Pos; |
| 560 if (m_Pos >= m_Size) { |
| 561 return; |
| 562 } |
| 563 int ch = m_pBuf[m_Pos++]; |
| 564 int type = PDF_CharType[ch]; |
| 565 while (1) { |
| 566 while (type == 'W') { |
| 567 if (m_Pos >= m_Size) { |
| 568 return; |
| 569 } |
| 570 ch = m_pBuf[m_Pos++]; |
| 571 type = PDF_CharType[ch]; |
| 572 } |
| 573 if (type != 'N') { |
| 574 m_Pos = command_startpos; |
| 575 return; |
| 482 } | 576 } |
| 483 while (1) { | 577 while (1) { |
| 484 if (m_WordSize < MAX_WORD_BUFFER) { | 578 while (type != 'W') { |
| 485 m_WordBuffer[m_WordSize++] = ch; | 579 if (m_Pos >= m_Size) { |
| 486 } | 580 return; |
| 487 if (type != 'N') { | |
| 488 bIsNumber = FALSE; | |
| 489 } | |
| 490 if (m_Size <= m_Pos) { | |
| 491 break; | |
| 492 } | 581 } |
| 493 ch = m_pBuf[m_Pos++]; | 582 ch = m_pBuf[m_Pos++]; |
| 494 type = PDF_CharType[ch]; | 583 type = PDF_CharType[ch]; |
| 495 if (type == 'D' || type == 'W') { | 584 } |
| 496 m_Pos --; | 585 while (type == 'W') { |
| 497 break; | 586 if (m_Pos >= m_Size) { |
| 498 } | 587 return; |
| 499 } | |
| 500 m_WordBuffer[m_WordSize] = 0; | |
| 501 if (bIsNumber) { | |
| 502 return Number; | |
| 503 } | |
| 504 if (m_WordBuffer[0] == '/') { | |
| 505 return Name; | |
| 506 } | |
| 507 if (m_WordSize == 4) { | |
| 508 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) { | |
| 509 m_pLastObj = CPDF_Boolean::Create(TRUE); | |
| 510 return Others; | |
| 511 } | |
| 512 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) { | |
| 513 m_pLastObj = CPDF_Null::Create(); | |
| 514 return Others; | |
| 515 } | |
| 516 } else if (m_WordSize == 5) { | |
| 517 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e')
{ | |
| 518 m_pLastObj = CPDF_Boolean::Create(FALSE); | |
| 519 return Others; | |
| 520 } | |
| 521 } | |
| 522 return Keyword; | |
| 523 } | |
| 524 void CPDF_StreamParser::SkipPathObject() | |
| 525 { | |
| 526 FX_DWORD command_startpos = m_Pos; | |
| 527 if (m_Pos >= m_Size) { | |
| 528 return; | |
| 529 } | |
| 530 int ch = m_pBuf[m_Pos++]; | |
| 531 int type = PDF_CharType[ch]; | |
| 532 while (1) { | |
| 533 while (type == 'W') { | |
| 534 if (m_Pos >= m_Size) { | |
| 535 return; | |
| 536 } | |
| 537 ch = m_pBuf[m_Pos++]; | |
| 538 type = PDF_CharType[ch]; | |
| 539 } | |
| 540 if (type != 'N') { | |
| 541 m_Pos = command_startpos; | |
| 542 return; | |
| 543 } | |
| 544 while (1) { | |
| 545 while (type != 'W') { | |
| 546 if (m_Pos >= m_Size) { | |
| 547 return; | |
| 548 } | |
| 549 ch = m_pBuf[m_Pos++]; | |
| 550 type = PDF_CharType[ch]; | |
| 551 } | |
| 552 while (type == 'W') { | |
| 553 if (m_Pos >= m_Size) { | |
| 554 return; | |
| 555 } | |
| 556 ch = m_pBuf[m_Pos++]; | |
| 557 type = PDF_CharType[ch]; | |
| 558 } | |
| 559 if (type == 'N') { | |
| 560 continue; | |
| 561 } | |
| 562 FX_DWORD op_startpos = m_Pos - 1; | |
| 563 while (type != 'W' && type != 'D') { | |
| 564 if (m_Pos >= m_Size) { | |
| 565 return; | |
| 566 } | |
| 567 ch = m_pBuf[m_Pos++]; | |
| 568 type = PDF_CharType[ch]; | |
| 569 } | |
| 570 if (m_Pos - op_startpos == 2) { | |
| 571 int op = m_pBuf[op_startpos]; | |
| 572 if (op == 'm' || op == 'l' || op == 'c' || op == 'v' || op == 'y
') { | |
| 573 command_startpos = m_Pos; | |
| 574 break; | |
| 575 } | |
| 576 } else if (m_Pos - op_startpos == 3) { | |
| 577 if (m_pBuf[op_startpos] == 'r' && m_pBuf[op_startpos + 1] == 'e'
) { | |
| 578 command_startpos = m_Pos; | |
| 579 break; | |
| 580 } | |
| 581 } | |
| 582 m_Pos = command_startpos; | |
| 583 return; | |
| 584 } | |
| 585 } | |
| 586 } | |
| 587 CPDF_Object* CPDF_StreamParser::ReadNextObject(FX_BOOL bAllowNestedArray, FX_BOO
L bInArray) | |
| 588 { | |
| 589 FX_BOOL bIsNumber; | |
| 590 GetNextWord(bIsNumber); | |
| 591 if (m_WordSize == 0) { | |
| 592 return NULL; | |
| 593 } | |
| 594 if (bIsNumber) { | |
| 595 m_WordBuffer[m_WordSize] = 0; | |
| 596 return CPDF_Number::Create(CFX_ByteStringC(m_WordBuffer, m_WordSize)); | |
| 597 } | |
| 598 int first_char = m_WordBuffer[0]; | |
| 599 if (first_char == '/') { | |
| 600 return CPDF_Name::Create(PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1
, m_WordSize - 1))); | |
| 601 } | |
| 602 if (first_char == '(') { | |
| 603 return CPDF_String::Create(ReadString()); | |
| 604 } | |
| 605 if (first_char == '<') { | |
| 606 if (m_WordSize == 1) { | |
| 607 return CPDF_String::Create(ReadHexString(), TRUE); | |
| 608 } | |
| 609 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); | |
| 610 while (1) { | |
| 611 GetNextWord(bIsNumber); | |
| 612 if (m_WordSize == 0) { | |
| 613 pDict->Release(); | |
| 614 return NULL; | |
| 615 } | |
| 616 if (m_WordSize == 2 && m_WordBuffer[0] == '>') { | |
| 617 break; | |
| 618 } | |
| 619 if (m_WordBuffer[0] != '/') { | |
| 620 pDict->Release(); | |
| 621 return NULL; | |
| 622 } | |
| 623 CFX_ByteString key = PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1
, m_WordSize - 1)); | |
| 624 CPDF_Object* pObj = ReadNextObject(TRUE); | |
| 625 if (pObj == NULL) { | |
| 626 if (pDict) { | |
| 627 pDict->Release(); | |
| 628 } | |
| 629 return NULL; | |
| 630 } | |
| 631 if (!key.IsEmpty()) { | |
| 632 pDict->SetAt(key, pObj); | |
| 633 } else { | |
| 634 pObj->Release(); | |
| 635 } | |
| 636 } | |
| 637 return pDict; | |
| 638 } | |
| 639 if (first_char == '[') { | |
| 640 if (!bAllowNestedArray && bInArray) { | |
| 641 return NULL; | |
| 642 } | |
| 643 CPDF_Array* pArray = CPDF_Array::Create(); | |
| 644 while (1) { | |
| 645 CPDF_Object* pObj = ReadNextObject(bAllowNestedArray, TRUE); | |
| 646 if (pObj == NULL) { | |
| 647 if (m_WordSize == 0 || m_WordBuffer[0] == ']') { | |
| 648 return pArray; | |
| 649 } | |
| 650 if (m_WordBuffer[0] == '[') { | |
| 651 continue; | |
| 652 } | |
| 653 } else { | |
| 654 pArray->Add(pObj); | |
| 655 } | |
| 656 } | |
| 657 } | |
| 658 if (m_WordSize == 4) { | |
| 659 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) { | |
| 660 return CPDF_Boolean::Create(TRUE); | |
| 661 } | |
| 662 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) { | |
| 663 return CPDF_Null::Create(); | |
| 664 } | |
| 665 } else if (m_WordSize == 5) { | |
| 666 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e')
{ | |
| 667 return CPDF_Boolean::Create(FALSE); | |
| 668 } | |
| 669 } | |
| 670 return NULL; | |
| 671 } | |
| 672 void CPDF_StreamParser::GetNextWord(FX_BOOL& bIsNumber) | |
| 673 { | |
| 674 m_WordSize = 0; | |
| 675 bIsNumber = TRUE; | |
| 676 if (m_Size <= m_Pos) { | |
| 677 return; | |
| 678 } | |
| 679 int ch = m_pBuf[m_Pos++]; | |
| 680 int type = PDF_CharType[ch]; | |
| 681 while (1) { | |
| 682 while (type == 'W') { | |
| 683 if (m_Size <= m_Pos) { | |
| 684 return; | |
| 685 } | |
| 686 ch = m_pBuf[m_Pos++]; | |
| 687 type = PDF_CharType[ch]; | |
| 688 } | |
| 689 if (ch != '%') { | |
| 690 break; | |
| 691 } | |
| 692 while (1) { | |
| 693 if (m_Size <= m_Pos) { | |
| 694 return; | |
| 695 } | |
| 696 ch = m_pBuf[m_Pos++]; | |
| 697 if (ch == '\r' || ch == '\n') { | |
| 698 break; | |
| 699 } | |
| 700 } | |
| 701 type = PDF_CharType[ch]; | |
| 702 } | |
| 703 if (type == 'D') { | |
| 704 bIsNumber = FALSE; | |
| 705 m_WordBuffer[m_WordSize++] = ch; | |
| 706 if (ch == '/') { | |
| 707 while (1) { | |
| 708 if (m_Size <= m_Pos) { | |
| 709 return; | |
| 710 } | |
| 711 ch = m_pBuf[m_Pos++]; | |
| 712 type = PDF_CharType[ch]; | |
| 713 if (type != 'R' && type != 'N') { | |
| 714 m_Pos --; | |
| 715 return; | |
| 716 } | |
| 717 if (m_WordSize < MAX_WORD_BUFFER) { | |
| 718 m_WordBuffer[m_WordSize++] = ch; | |
| 719 } | |
| 720 } | |
| 721 } else if (ch == '<') { | |
| 722 if (m_Size <= m_Pos) { | |
| 723 return; | |
| 724 } | |
| 725 ch = m_pBuf[m_Pos++]; | |
| 726 if (ch == '<') { | |
| 727 m_WordBuffer[m_WordSize++] = ch; | |
| 728 } else { | |
| 729 m_Pos --; | |
| 730 } | |
| 731 } else if (ch == '>') { | |
| 732 if (m_Size <= m_Pos) { | |
| 733 return; | |
| 734 } | |
| 735 ch = m_pBuf[m_Pos++]; | |
| 736 if (ch == '>') { | |
| 737 m_WordBuffer[m_WordSize++] = ch; | |
| 738 } else { | |
| 739 m_Pos --; | |
| 740 } | |
| 741 } | |
| 742 return; | |
| 743 } | |
| 744 while (1) { | |
| 745 if (m_WordSize < MAX_WORD_BUFFER) { | |
| 746 m_WordBuffer[m_WordSize++] = ch; | |
| 747 } | |
| 748 if (type != 'N') { | |
| 749 bIsNumber = FALSE; | |
| 750 } | |
| 751 if (m_Size <= m_Pos) { | |
| 752 return; | |
| 753 } | 588 } |
| 754 ch = m_pBuf[m_Pos++]; | 589 ch = m_pBuf[m_Pos++]; |
| 755 type = PDF_CharType[ch]; | 590 type = PDF_CharType[ch]; |
| 756 if (type == 'D' || type == 'W') { | 591 } |
| 757 m_Pos --; | 592 if (type == 'N') { |
| 758 break; | 593 continue; |
| 759 } | 594 } |
| 760 } | 595 FX_DWORD op_startpos = m_Pos - 1; |
| 761 } | 596 while (type != 'W' && type != 'D') { |
| 762 CFX_ByteString CPDF_StreamParser::ReadString() | 597 if (m_Pos >= m_Size) { |
| 763 { | 598 return; |
| 599 } |
| 600 ch = m_pBuf[m_Pos++]; |
| 601 type = PDF_CharType[ch]; |
| 602 } |
| 603 if (m_Pos - op_startpos == 2) { |
| 604 int op = m_pBuf[op_startpos]; |
| 605 if (op == 'm' || op == 'l' || op == 'c' || op == 'v' || op == 'y') { |
| 606 command_startpos = m_Pos; |
| 607 break; |
| 608 } |
| 609 } else if (m_Pos - op_startpos == 3) { |
| 610 if (m_pBuf[op_startpos] == 'r' && m_pBuf[op_startpos + 1] == 'e') { |
| 611 command_startpos = m_Pos; |
| 612 break; |
| 613 } |
| 614 } |
| 615 m_Pos = command_startpos; |
| 616 return; |
| 617 } |
| 618 } |
| 619 } |
| 620 CPDF_Object* CPDF_StreamParser::ReadNextObject(FX_BOOL bAllowNestedArray, |
| 621 FX_BOOL bInArray) { |
| 622 FX_BOOL bIsNumber; |
| 623 GetNextWord(bIsNumber); |
| 624 if (m_WordSize == 0) { |
| 625 return NULL; |
| 626 } |
| 627 if (bIsNumber) { |
| 628 m_WordBuffer[m_WordSize] = 0; |
| 629 return CPDF_Number::Create(CFX_ByteStringC(m_WordBuffer, m_WordSize)); |
| 630 } |
| 631 int first_char = m_WordBuffer[0]; |
| 632 if (first_char == '/') { |
| 633 return CPDF_Name::Create( |
| 634 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); |
| 635 } |
| 636 if (first_char == '(') { |
| 637 return CPDF_String::Create(ReadString()); |
| 638 } |
| 639 if (first_char == '<') { |
| 640 if (m_WordSize == 1) { |
| 641 return CPDF_String::Create(ReadHexString(), TRUE); |
| 642 } |
| 643 CPDF_Dictionary* pDict = CPDF_Dictionary::Create(); |
| 644 while (1) { |
| 645 GetNextWord(bIsNumber); |
| 646 if (m_WordSize == 0) { |
| 647 pDict->Release(); |
| 648 return NULL; |
| 649 } |
| 650 if (m_WordSize == 2 && m_WordBuffer[0] == '>') { |
| 651 break; |
| 652 } |
| 653 if (m_WordBuffer[0] != '/') { |
| 654 pDict->Release(); |
| 655 return NULL; |
| 656 } |
| 657 CFX_ByteString key = |
| 658 PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)); |
| 659 CPDF_Object* pObj = ReadNextObject(TRUE); |
| 660 if (pObj == NULL) { |
| 661 if (pDict) { |
| 662 pDict->Release(); |
| 663 } |
| 664 return NULL; |
| 665 } |
| 666 if (!key.IsEmpty()) { |
| 667 pDict->SetAt(key, pObj); |
| 668 } else { |
| 669 pObj->Release(); |
| 670 } |
| 671 } |
| 672 return pDict; |
| 673 } |
| 674 if (first_char == '[') { |
| 675 if (!bAllowNestedArray && bInArray) { |
| 676 return NULL; |
| 677 } |
| 678 CPDF_Array* pArray = CPDF_Array::Create(); |
| 679 while (1) { |
| 680 CPDF_Object* pObj = ReadNextObject(bAllowNestedArray, TRUE); |
| 681 if (pObj == NULL) { |
| 682 if (m_WordSize == 0 || m_WordBuffer[0] == ']') { |
| 683 return pArray; |
| 684 } |
| 685 if (m_WordBuffer[0] == '[') { |
| 686 continue; |
| 687 } |
| 688 } else { |
| 689 pArray->Add(pObj); |
| 690 } |
| 691 } |
| 692 } |
| 693 if (m_WordSize == 4) { |
| 694 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_TRUE) { |
| 695 return CPDF_Boolean::Create(TRUE); |
| 696 } |
| 697 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_NULL) { |
| 698 return CPDF_Null::Create(); |
| 699 } |
| 700 } else if (m_WordSize == 5) { |
| 701 if (*(FX_DWORD*)m_WordBuffer == FXDWORD_FALS && m_WordBuffer[4] == 'e') { |
| 702 return CPDF_Boolean::Create(FALSE); |
| 703 } |
| 704 } |
| 705 return NULL; |
| 706 } |
| 707 void CPDF_StreamParser::GetNextWord(FX_BOOL& bIsNumber) { |
| 708 m_WordSize = 0; |
| 709 bIsNumber = TRUE; |
| 710 if (m_Size <= m_Pos) { |
| 711 return; |
| 712 } |
| 713 int ch = m_pBuf[m_Pos++]; |
| 714 int type = PDF_CharType[ch]; |
| 715 while (1) { |
| 716 while (type == 'W') { |
| 717 if (m_Size <= m_Pos) { |
| 718 return; |
| 719 } |
| 720 ch = m_pBuf[m_Pos++]; |
| 721 type = PDF_CharType[ch]; |
| 722 } |
| 723 if (ch != '%') { |
| 724 break; |
| 725 } |
| 726 while (1) { |
| 727 if (m_Size <= m_Pos) { |
| 728 return; |
| 729 } |
| 730 ch = m_pBuf[m_Pos++]; |
| 731 if (ch == '\r' || ch == '\n') { |
| 732 break; |
| 733 } |
| 734 } |
| 735 type = PDF_CharType[ch]; |
| 736 } |
| 737 if (type == 'D') { |
| 738 bIsNumber = FALSE; |
| 739 m_WordBuffer[m_WordSize++] = ch; |
| 740 if (ch == '/') { |
| 741 while (1) { |
| 742 if (m_Size <= m_Pos) { |
| 743 return; |
| 744 } |
| 745 ch = m_pBuf[m_Pos++]; |
| 746 type = PDF_CharType[ch]; |
| 747 if (type != 'R' && type != 'N') { |
| 748 m_Pos--; |
| 749 return; |
| 750 } |
| 751 if (m_WordSize < MAX_WORD_BUFFER) { |
| 752 m_WordBuffer[m_WordSize++] = ch; |
| 753 } |
| 754 } |
| 755 } else if (ch == '<') { |
| 756 if (m_Size <= m_Pos) { |
| 757 return; |
| 758 } |
| 759 ch = m_pBuf[m_Pos++]; |
| 760 if (ch == '<') { |
| 761 m_WordBuffer[m_WordSize++] = ch; |
| 762 } else { |
| 763 m_Pos--; |
| 764 } |
| 765 } else if (ch == '>') { |
| 766 if (m_Size <= m_Pos) { |
| 767 return; |
| 768 } |
| 769 ch = m_pBuf[m_Pos++]; |
| 770 if (ch == '>') { |
| 771 m_WordBuffer[m_WordSize++] = ch; |
| 772 } else { |
| 773 m_Pos--; |
| 774 } |
| 775 } |
| 776 return; |
| 777 } |
| 778 while (1) { |
| 779 if (m_WordSize < MAX_WORD_BUFFER) { |
| 780 m_WordBuffer[m_WordSize++] = ch; |
| 781 } |
| 782 if (type != 'N') { |
| 783 bIsNumber = FALSE; |
| 784 } |
| 764 if (m_Size <= m_Pos) { | 785 if (m_Size <= m_Pos) { |
| 765 return CFX_ByteString(); | 786 return; |
| 766 } | 787 } |
| 767 int ch = m_pBuf[m_Pos++]; | 788 ch = m_pBuf[m_Pos++]; |
| 768 CFX_ByteTextBuf buf; | 789 type = PDF_CharType[ch]; |
| 769 int parlevel = 0; | 790 if (type == 'D' || type == 'W') { |
| 770 int status = 0, iEscCode = 0; | 791 m_Pos--; |
| 771 while (1) { | 792 break; |
| 772 switch (status) { | 793 } |
| 773 case 0: | 794 } |
| 774 if (ch == ')') { | 795 } |
| 775 if (parlevel == 0) { | 796 CFX_ByteString CPDF_StreamParser::ReadString() { |
| 776 if (buf.GetLength() > MAX_STRING_LENGTH) { | 797 if (m_Size <= m_Pos) { |
| 777 return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LE
NGTH); | 798 return CFX_ByteString(); |
| 778 } | 799 } |
| 779 return buf.GetByteString(); | 800 int ch = m_pBuf[m_Pos++]; |
| 780 } | 801 CFX_ByteTextBuf buf; |
| 781 parlevel --; | 802 int parlevel = 0; |
| 782 buf.AppendChar(')'); | 803 int status = 0, iEscCode = 0; |
| 783 } else if (ch == '(') { | 804 while (1) { |
| 784 parlevel ++; | 805 switch (status) { |
| 785 buf.AppendChar('('); | 806 case 0: |
| 786 } else if (ch == '\\') { | 807 if (ch == ')') { |
| 787 status = 1; | 808 if (parlevel == 0) { |
| 788 } else { | 809 if (buf.GetLength() > MAX_STRING_LENGTH) { |
| 789 buf.AppendChar((char)ch); | 810 return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH); |
| 790 } | 811 } |
| 791 break; | 812 return buf.GetByteString(); |
| 792 case 1: | 813 } |
| 793 if (ch >= '0' && ch <= '7') { | 814 parlevel--; |
| 794 iEscCode = ch - '0'; | 815 buf.AppendChar(')'); |
| 795 status = 2; | 816 } else if (ch == '(') { |
| 796 break; | 817 parlevel++; |
| 797 } | 818 buf.AppendChar('('); |
| 798 if (ch == 'n') { | 819 } else if (ch == '\\') { |
| 799 buf.AppendChar('\n'); | 820 status = 1; |
| 800 } else if (ch == 'r') { | 821 } else { |
| 801 buf.AppendChar('\r'); | 822 buf.AppendChar((char)ch); |
| 802 } else if (ch == 't') { | 823 } |
| 803 buf.AppendChar('\t'); | 824 break; |
| 804 } else if (ch == 'b') { | 825 case 1: |
| 805 buf.AppendChar('\b'); | 826 if (ch >= '0' && ch <= '7') { |
| 806 } else if (ch == 'f') { | 827 iEscCode = ch - '0'; |
| 807 buf.AppendChar('\f'); | 828 status = 2; |
| 808 } else if (ch == '\r') { | 829 break; |
| 809 status = 4; | 830 } |
| 810 break; | 831 if (ch == 'n') { |
| 811 } else if (ch == '\n') { | 832 buf.AppendChar('\n'); |
| 812 } else { | 833 } else if (ch == 'r') { |
| 813 buf.AppendChar(ch); | 834 buf.AppendChar('\r'); |
| 814 } | 835 } else if (ch == 't') { |
| 815 status = 0; | 836 buf.AppendChar('\t'); |
| 816 break; | 837 } else if (ch == 'b') { |
| 817 case 2: | 838 buf.AppendChar('\b'); |
| 818 if (ch >= '0' && ch <= '7') { | 839 } else if (ch == 'f') { |
| 819 iEscCode = iEscCode * 8 + ch - '0'; | 840 buf.AppendChar('\f'); |
| 820 status = 3; | 841 } else if (ch == '\r') { |
| 821 } else { | 842 status = 4; |
| 822 buf.AppendChar(iEscCode); | 843 break; |
| 823 status = 0; | 844 } else if (ch == '\n') { |
| 824 continue; | 845 } else { |
| 825 } | 846 buf.AppendChar(ch); |
| 826 break; | 847 } |
| 827 case 3: | 848 status = 0; |
| 828 if (ch >= '0' && ch <= '7') { | 849 break; |
| 829 iEscCode = iEscCode * 8 + ch - '0'; | 850 case 2: |
| 830 buf.AppendChar(iEscCode); | 851 if (ch >= '0' && ch <= '7') { |
| 831 status = 0; | 852 iEscCode = iEscCode * 8 + ch - '0'; |
| 832 } else { | 853 status = 3; |
| 833 buf.AppendChar(iEscCode); | 854 } else { |
| 834 status = 0; | 855 buf.AppendChar(iEscCode); |
| 835 continue; | 856 status = 0; |
| 836 } | 857 continue; |
| 837 break; | 858 } |
| 838 case 4: | 859 break; |
| 839 status = 0; | 860 case 3: |
| 840 if (ch != '\n') { | 861 if (ch >= '0' && ch <= '7') { |
| 841 continue; | 862 iEscCode = iEscCode * 8 + ch - '0'; |
| 842 } | 863 buf.AppendChar(iEscCode); |
| 843 break; | 864 status = 0; |
| 844 } | 865 } else { |
| 845 if (m_Size <= m_Pos) { | 866 buf.AppendChar(iEscCode); |
| 846 break; | 867 status = 0; |
| 847 } | 868 continue; |
| 848 ch = m_pBuf[m_Pos++]; | 869 } |
| 849 } | 870 break; |
| 850 if (m_Size > m_Pos) { | 871 case 4: |
| 851 ch = m_pBuf[m_Pos++]; | 872 status = 0; |
| 852 } | 873 if (ch != '\n') { |
| 853 if (buf.GetLength() > MAX_STRING_LENGTH) { | 874 continue; |
| 854 return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH); | 875 } |
| 855 } | 876 break; |
| 856 return buf.GetByteString(); | 877 } |
| 857 } | |
| 858 CFX_ByteString CPDF_StreamParser::ReadHexString() | |
| 859 { | |
| 860 if (m_Size <= m_Pos) { | 878 if (m_Size <= m_Pos) { |
| 861 return CFX_ByteString(); | 879 break; |
| 862 } | 880 } |
| 863 int ch = m_pBuf[m_Pos++]; | 881 ch = m_pBuf[m_Pos++]; |
| 864 CFX_ByteTextBuf buf; | 882 } |
| 865 FX_BOOL bFirst = TRUE; | 883 if (m_Size > m_Pos) { |
| 866 int code = 0; | 884 ch = m_pBuf[m_Pos++]; |
| 867 while (1) { | 885 } |
| 868 if (ch == '>') { | 886 if (buf.GetLength() > MAX_STRING_LENGTH) { |
| 869 break; | 887 return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH); |
| 870 } | 888 } |
| 871 if (ch >= '0' && ch <= '9') { | 889 return buf.GetByteString(); |
| 872 if (bFirst) { | 890 } |
| 873 code = (ch - '0') * 16; | 891 CFX_ByteString CPDF_StreamParser::ReadHexString() { |
| 874 } else { | 892 if (m_Size <= m_Pos) { |
| 875 code += ch - '0'; | 893 return CFX_ByteString(); |
| 876 buf.AppendChar((char)code); | 894 } |
| 877 } | 895 int ch = m_pBuf[m_Pos++]; |
| 878 bFirst = !bFirst; | 896 CFX_ByteTextBuf buf; |
| 879 } else if (ch >= 'A' && ch <= 'F') { | 897 FX_BOOL bFirst = TRUE; |
| 880 if (bFirst) { | 898 int code = 0; |
| 881 code = (ch - 'A' + 10) * 16; | 899 while (1) { |
| 882 } else { | 900 if (ch == '>') { |
| 883 code += ch - 'A' + 10; | 901 break; |
| 884 buf.AppendChar((char)code); | 902 } |
| 885 } | 903 if (ch >= '0' && ch <= '9') { |
| 886 bFirst = !bFirst; | 904 if (bFirst) { |
| 887 } else if (ch >= 'a' && ch <= 'f') { | 905 code = (ch - '0') * 16; |
| 888 if (bFirst) { | 906 } else { |
| 889 code = (ch - 'a' + 10) * 16; | 907 code += ch - '0'; |
| 890 } else { | |
| 891 code += ch - 'a' + 10; | |
| 892 buf.AppendChar((char)code); | |
| 893 } | |
| 894 bFirst = !bFirst; | |
| 895 } | |
| 896 if (m_Size <= m_Pos) { | |
| 897 break; | |
| 898 } | |
| 899 ch = m_pBuf[m_Pos++]; | |
| 900 } | |
| 901 if (!bFirst) { | |
| 902 buf.AppendChar((char)code); | 908 buf.AppendChar((char)code); |
| 903 } | 909 } |
| 904 if (buf.GetLength() > MAX_STRING_LENGTH) { | 910 bFirst = !bFirst; |
| 905 return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH); | 911 } else if (ch >= 'A' && ch <= 'F') { |
| 906 } | 912 if (bFirst) { |
| 907 return buf.GetByteString(); | 913 code = (ch - 'A' + 10) * 16; |
| 908 } | 914 } else { |
| 909 #define PAGEPARSE_STAGE_GETCONTENT» » 1 | 915 code += ch - 'A' + 10; |
| 910 #define PAGEPARSE_STAGE_PARSE» » » 2 | 916 buf.AppendChar((char)code); |
| 911 #define PAGEPARSE_STAGE_CHECKCLIP» » 3 | 917 } |
| 912 CPDF_ContentParser::CPDF_ContentParser() | 918 bFirst = !bFirst; |
| 913 { | 919 } else if (ch >= 'a' && ch <= 'f') { |
| 914 m_pParser = NULL; | 920 if (bFirst) { |
| 915 m_pStreamArray = NULL; | 921 code = (ch - 'a' + 10) * 16; |
| 916 m_pSingleStream = NULL; | 922 } else { |
| 917 m_pData = NULL; | 923 code += ch - 'a' + 10; |
| 918 m_Status = Ready; | 924 buf.AppendChar((char)code); |
| 919 m_pType3Char = NULL; | 925 } |
| 920 } | 926 bFirst = !bFirst; |
| 921 CPDF_ContentParser::~CPDF_ContentParser() | 927 } |
| 922 { | 928 if (m_Size <= m_Pos) { |
| 923 Clear(); | 929 break; |
| 924 } | 930 } |
| 925 void CPDF_ContentParser::Clear() | 931 ch = m_pBuf[m_Pos++]; |
| 926 { | 932 } |
| 927 delete m_pParser; | 933 if (!bFirst) { |
| 928 delete m_pSingleStream; | 934 buf.AppendChar((char)code); |
| 929 if (m_pStreamArray) { | 935 } |
| 930 for (FX_DWORD i = 0; i < m_nStreams; i ++) | 936 if (buf.GetLength() > MAX_STRING_LENGTH) { |
| 931 delete m_pStreamArray[i]; | 937 return CFX_ByteString(buf.GetBuffer(), MAX_STRING_LENGTH); |
| 932 FX_Free(m_pStreamArray); | 938 } |
| 933 } | 939 return buf.GetByteString(); |
| 934 if (m_pData && m_pSingleStream == NULL) { | 940 } |
| 935 FX_Free((void*)m_pData); | 941 #define PAGEPARSE_STAGE_GETCONTENT 1 |
| 936 } | 942 #define PAGEPARSE_STAGE_PARSE 2 |
| 937 m_pParser = NULL; | 943 #define PAGEPARSE_STAGE_CHECKCLIP 3 |
| 938 m_pStreamArray = NULL; | 944 CPDF_ContentParser::CPDF_ContentParser() { |
| 939 m_pSingleStream = NULL; | 945 m_pParser = NULL; |
| 940 m_pData = NULL; | 946 m_pStreamArray = NULL; |
| 941 m_Status = Ready; | 947 m_pSingleStream = NULL; |
| 942 } | 948 m_pData = NULL; |
| 943 void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions) | 949 m_Status = Ready; |
| 944 { | 950 m_pType3Char = NULL; |
| 945 if (m_Status != Ready || pPage == NULL || pPage->m_pDocument == NULL || pPag
e->m_pFormDict == NULL) { | 951 } |
| 946 m_Status = Done; | 952 CPDF_ContentParser::~CPDF_ContentParser() { |
| 947 return; | 953 Clear(); |
| 948 } | 954 } |
| 949 m_pObjects = pPage; | 955 void CPDF_ContentParser::Clear() { |
| 950 m_bForm = FALSE; | 956 delete m_pParser; |
| 951 if (pOptions) { | 957 delete m_pSingleStream; |
| 952 m_Options = *pOptions; | 958 if (m_pStreamArray) { |
| 953 } | 959 for (FX_DWORD i = 0; i < m_nStreams; i++) |
| 954 m_Status = ToBeContinued; | 960 delete m_pStreamArray[i]; |
| 955 m_InternalStage = PAGEPARSE_STAGE_GETCONTENT; | 961 FX_Free(m_pStreamArray); |
| 956 m_CurrentOffset = 0; | 962 } |
| 957 CPDF_Object* pContent = pPage->m_pFormDict->GetElementValue(FX_BSTRC("Conten
ts")); | 963 if (m_pData && m_pSingleStream == NULL) { |
| 958 if (pContent == NULL) { | 964 FX_Free((void*)m_pData); |
| 959 m_Status = Done; | 965 } |
| 960 return; | 966 m_pParser = NULL; |
| 961 } | 967 m_pStreamArray = NULL; |
| 962 if (pContent->GetType() == PDFOBJ_STREAM) { | 968 m_pSingleStream = NULL; |
| 963 m_nStreams = 0; | 969 m_pData = NULL; |
| 964 m_pSingleStream = new CPDF_StreamAcc; | 970 m_Status = Ready; |
| 965 m_pSingleStream->LoadAllData((CPDF_Stream*)pContent, FALSE); | 971 } |
| 966 } else if (pContent->GetType() == PDFOBJ_ARRAY) { | 972 void CPDF_ContentParser::Start(CPDF_Page* pPage, CPDF_ParseOptions* pOptions) { |
| 967 CPDF_Array* pArray = (CPDF_Array*)pContent; | 973 if (m_Status != Ready || pPage == NULL || pPage->m_pDocument == NULL || |
| 968 m_nStreams = pArray->GetCount(); | 974 pPage->m_pFormDict == NULL) { |
| 969 if (m_nStreams == 0) { | 975 m_Status = Done; |
| 970 m_Status = Done; | 976 return; |
| 971 return; | 977 } |
| 972 } | 978 m_pObjects = pPage; |
| 973 m_pStreamArray = FX_Alloc(CPDF_StreamAcc*, m_nStreams); | 979 m_bForm = FALSE; |
| 974 } else { | 980 if (pOptions) { |
| 975 m_Status = Done; | 981 m_Options = *pOptions; |
| 976 return; | 982 } |
| 977 } | 983 m_Status = ToBeContinued; |
| 978 } | 984 m_InternalStage = PAGEPARSE_STAGE_GETCONTENT; |
| 979 void CPDF_ContentParser::Start(CPDF_Form* pForm, CPDF_AllStates* pGraphicStates, | 985 m_CurrentOffset = 0; |
| 980 CFX_AffineMatrix* pParentMatrix, CPDF_Type3Char*
pType3Char, CPDF_ParseOptions* pOptions, int level) | 986 CPDF_Object* pContent = |
| 981 { | 987 pPage->m_pFormDict->GetElementValue(FX_BSTRC("Contents")); |
| 982 m_pType3Char = pType3Char; | 988 if (pContent == NULL) { |
| 983 m_pObjects = pForm; | 989 m_Status = Done; |
| 984 m_bForm = TRUE; | 990 return; |
| 985 CFX_AffineMatrix form_matrix = pForm->m_pFormDict->GetMatrix(FX_BSTRC("Matri
x")); | 991 } |
| 986 if (pGraphicStates) { | 992 if (pContent->GetType() == PDFOBJ_STREAM) { |
| 987 form_matrix.Concat(pGraphicStates->m_CTM); | |
| 988 } | |
| 989 CPDF_Array* pBBox = pForm->m_pFormDict->GetArray(FX_BSTRC("BBox")); | |
| 990 CFX_FloatRect form_bbox; | |
| 991 CPDF_Path ClipPath; | |
| 992 if (pBBox) { | |
| 993 form_bbox = pBBox->GetRect(); | |
| 994 ClipPath.New(); | |
| 995 ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, f
orm_bbox.top); | |
| 996 ClipPath.Transform(&form_matrix); | |
| 997 if (pParentMatrix) { | |
| 998 ClipPath.Transform(pParentMatrix); | |
| 999 } | |
| 1000 form_bbox.Transform(&form_matrix); | |
| 1001 if (pParentMatrix) { | |
| 1002 form_bbox.Transform(pParentMatrix); | |
| 1003 } | |
| 1004 } | |
| 1005 CPDF_Dictionary* pResources = pForm->m_pFormDict->GetDict(FX_BSTRC("Resource
s")); | |
| 1006 m_pParser = new CPDF_StreamContentParser( | |
| 1007 pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources, | |
| 1008 pParentMatrix, pForm, pResources, &form_bbox, pOptions, pGraphicStates, | |
| 1009 level); | |
| 1010 | |
| 1011 m_pParser->GetCurStates()->m_CTM = form_matrix; | |
| 1012 m_pParser->GetCurStates()->m_ParentMatrix = form_matrix; | |
| 1013 if (ClipPath.NotNull()) { | |
| 1014 m_pParser->GetCurStates()->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDIN
G, TRUE); | |
| 1015 } | |
| 1016 if (pForm->m_Transparency & PDFTRANS_GROUP) { | |
| 1017 CPDF_GeneralStateData* pData = m_pParser->GetCurStates()->m_GeneralState
.GetModify(); | |
| 1018 pData->m_BlendType = FXDIB_BLEND_NORMAL; | |
| 1019 pData->m_StrokeAlpha = 1.0f; | |
| 1020 pData->m_FillAlpha = 1.0f; | |
| 1021 pData->m_pSoftMask = NULL; | |
| 1022 } | |
| 1023 m_nStreams = 0; | 993 m_nStreams = 0; |
| 1024 m_pSingleStream = new CPDF_StreamAcc; | 994 m_pSingleStream = new CPDF_StreamAcc; |
| 1025 if (pForm->m_pDocument) { | 995 m_pSingleStream->LoadAllData((CPDF_Stream*)pContent, FALSE); |
| 1026 m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE); | 996 } else if (pContent->GetType() == PDFOBJ_ARRAY) { |
| 1027 } else { | 997 CPDF_Array* pArray = (CPDF_Array*)pContent; |
| 1028 m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE); | 998 m_nStreams = pArray->GetCount(); |
| 1029 } | 999 if (m_nStreams == 0) { |
| 1030 m_pData = (uint8_t*)m_pSingleStream->GetData(); | 1000 m_Status = Done; |
| 1031 m_Size = m_pSingleStream->GetSize(); | 1001 return; |
| 1032 m_Status = ToBeContinued; | 1002 } |
| 1033 m_InternalStage = PAGEPARSE_STAGE_PARSE; | 1003 m_pStreamArray = FX_Alloc(CPDF_StreamAcc*, m_nStreams); |
| 1034 m_CurrentOffset = 0; | 1004 } else { |
| 1035 } | 1005 m_Status = Done; |
| 1036 void CPDF_ContentParser::Continue(IFX_Pause* pPause) | 1006 return; |
| 1037 { | 1007 } |
| 1038 int steps = 0; | 1008 } |
| 1039 while (m_Status == ToBeContinued) { | 1009 void CPDF_ContentParser::Start(CPDF_Form* pForm, |
| 1040 if (m_InternalStage == PAGEPARSE_STAGE_GETCONTENT) { | 1010 CPDF_AllStates* pGraphicStates, |
| 1041 if (m_CurrentOffset == m_nStreams) { | 1011 CFX_AffineMatrix* pParentMatrix, |
| 1042 if (m_pStreamArray) { | 1012 CPDF_Type3Char* pType3Char, |
| 1043 m_Size = 0; | 1013 CPDF_ParseOptions* pOptions, |
| 1044 FX_DWORD i; | 1014 int level) { |
| 1045 for (i = 0; i < m_nStreams; i ++) { | 1015 m_pType3Char = pType3Char; |
| 1046 FX_DWORD size = m_pStreamArray[i]->GetSize(); | 1016 m_pObjects = pForm; |
| 1047 if (m_Size + size + 1 <= m_Size) { | 1017 m_bForm = TRUE; |
| 1048 m_Status = Done; | 1018 CFX_AffineMatrix form_matrix = |
| 1049 return; | 1019 pForm->m_pFormDict->GetMatrix(FX_BSTRC("Matrix")); |
| 1050 } | 1020 if (pGraphicStates) { |
| 1051 m_Size += size + 1; | 1021 form_matrix.Concat(pGraphicStates->m_CTM); |
| 1052 } | 1022 } |
| 1053 m_pData = FX_Alloc(uint8_t, m_Size); | 1023 CPDF_Array* pBBox = pForm->m_pFormDict->GetArray(FX_BSTRC("BBox")); |
| 1054 FX_DWORD pos = 0; | 1024 CFX_FloatRect form_bbox; |
| 1055 for (i = 0; i < m_nStreams; i ++) { | 1025 CPDF_Path ClipPath; |
| 1056 FXSYS_memcpy(m_pData + pos, m_pStreamArray[i]->GetData()
, m_pStreamArray[i]->GetSize()); | 1026 if (pBBox) { |
| 1057 pos += m_pStreamArray[i]->GetSize() + 1; | 1027 form_bbox = pBBox->GetRect(); |
| 1058 m_pData[pos - 1] = ' '; | 1028 ClipPath.New(); |
| 1059 delete m_pStreamArray[i]; | 1029 ClipPath.AppendRect(form_bbox.left, form_bbox.bottom, form_bbox.right, |
| 1060 } | 1030 form_bbox.top); |
| 1061 FX_Free(m_pStreamArray); | 1031 ClipPath.Transform(&form_matrix); |
| 1062 m_pStreamArray = NULL; | 1032 if (pParentMatrix) { |
| 1063 } else { | 1033 ClipPath.Transform(pParentMatrix); |
| 1064 m_pData = (uint8_t*)m_pSingleStream->GetData(); | 1034 } |
| 1065 m_Size = m_pSingleStream->GetSize(); | 1035 form_bbox.Transform(&form_matrix); |
| 1066 } | 1036 if (pParentMatrix) { |
| 1067 m_InternalStage = PAGEPARSE_STAGE_PARSE; | 1037 form_bbox.Transform(pParentMatrix); |
| 1068 m_CurrentOffset = 0; | 1038 } |
| 1069 } else { | 1039 } |
| 1070 CPDF_Array* pContent = m_pObjects->m_pFormDict->GetArray(FX_BSTR
C("Contents")); | 1040 CPDF_Dictionary* pResources = |
| 1071 m_pStreamArray[m_CurrentOffset] = new CPDF_StreamAcc; | 1041 pForm->m_pFormDict->GetDict(FX_BSTRC("Resources")); |
| 1072 CPDF_Stream* pStreamObj = (CPDF_Stream*)(pContent ? pContent->Ge
tElementValue(m_CurrentOffset) : NULL); | 1042 m_pParser = new CPDF_StreamContentParser( |
| 1073 m_pStreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, FALSE); | 1043 pForm->m_pDocument, pForm->m_pPageResources, pForm->m_pResources, |
| 1074 m_CurrentOffset ++; | 1044 pParentMatrix, pForm, pResources, &form_bbox, pOptions, pGraphicStates, |
| 1045 level); |
| 1046 |
| 1047 m_pParser->GetCurStates()->m_CTM = form_matrix; |
| 1048 m_pParser->GetCurStates()->m_ParentMatrix = form_matrix; |
| 1049 if (ClipPath.NotNull()) { |
| 1050 m_pParser->GetCurStates()->m_ClipPath.AppendPath(ClipPath, FXFILL_WINDING, |
| 1051 TRUE); |
| 1052 } |
| 1053 if (pForm->m_Transparency & PDFTRANS_GROUP) { |
| 1054 CPDF_GeneralStateData* pData = |
| 1055 m_pParser->GetCurStates()->m_GeneralState.GetModify(); |
| 1056 pData->m_BlendType = FXDIB_BLEND_NORMAL; |
| 1057 pData->m_StrokeAlpha = 1.0f; |
| 1058 pData->m_FillAlpha = 1.0f; |
| 1059 pData->m_pSoftMask = NULL; |
| 1060 } |
| 1061 m_nStreams = 0; |
| 1062 m_pSingleStream = new CPDF_StreamAcc; |
| 1063 if (pForm->m_pDocument) { |
| 1064 m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE); |
| 1065 } else { |
| 1066 m_pSingleStream->LoadAllData(pForm->m_pFormStream, FALSE); |
| 1067 } |
| 1068 m_pData = (uint8_t*)m_pSingleStream->GetData(); |
| 1069 m_Size = m_pSingleStream->GetSize(); |
| 1070 m_Status = ToBeContinued; |
| 1071 m_InternalStage = PAGEPARSE_STAGE_PARSE; |
| 1072 m_CurrentOffset = 0; |
| 1073 } |
| 1074 void CPDF_ContentParser::Continue(IFX_Pause* pPause) { |
| 1075 int steps = 0; |
| 1076 while (m_Status == ToBeContinued) { |
| 1077 if (m_InternalStage == PAGEPARSE_STAGE_GETCONTENT) { |
| 1078 if (m_CurrentOffset == m_nStreams) { |
| 1079 if (m_pStreamArray) { |
| 1080 m_Size = 0; |
| 1081 FX_DWORD i; |
| 1082 for (i = 0; i < m_nStreams; i++) { |
| 1083 FX_DWORD size = m_pStreamArray[i]->GetSize(); |
| 1084 if (m_Size + size + 1 <= m_Size) { |
| 1085 m_Status = Done; |
| 1086 return; |
| 1075 } | 1087 } |
| 1076 } | 1088 m_Size += size + 1; |
| 1077 if (m_InternalStage == PAGEPARSE_STAGE_PARSE) { | 1089 } |
| 1078 if (!m_pParser) { | 1090 m_pData = FX_Alloc(uint8_t, m_Size); |
| 1079 m_pParser = new CPDF_StreamContentParser( | 1091 FX_DWORD pos = 0; |
| 1080 m_pObjects->m_pDocument, m_pObjects->m_pPageResources, | 1092 for (i = 0; i < m_nStreams; i++) { |
| 1081 nullptr, nullptr, m_pObjects, m_pObjects->m_pResources, | 1093 FXSYS_memcpy(m_pData + pos, m_pStreamArray[i]->GetData(), |
| 1082 &m_pObjects->m_BBox, &m_Options, nullptr, 0); | 1094 m_pStreamArray[i]->GetSize()); |
| 1083 m_pParser->GetCurStates()->m_ColorState.GetModify()->Default(); | 1095 pos += m_pStreamArray[i]->GetSize() + 1; |
| 1084 } | 1096 m_pData[pos - 1] = ' '; |
| 1085 if (m_CurrentOffset >= m_Size) { | 1097 delete m_pStreamArray[i]; |
| 1086 m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP; | 1098 } |
| 1087 } else { | 1099 FX_Free(m_pStreamArray); |
| 1088 m_CurrentOffset += m_pParser->Parse(m_pData + m_CurrentOffset, m
_Size - m_CurrentOffset, PARSE_STEP_LIMIT); | 1100 m_pStreamArray = NULL; |
| 1089 if (m_pParser->ShouldAbort()) { | 1101 } else { |
| 1090 m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP; | 1102 m_pData = (uint8_t*)m_pSingleStream->GetData(); |
| 1091 continue; | 1103 m_Size = m_pSingleStream->GetSize(); |
| 1092 } | 1104 } |
| 1093 } | 1105 m_InternalStage = PAGEPARSE_STAGE_PARSE; |
| 1094 } | 1106 m_CurrentOffset = 0; |
| 1095 if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) { | 1107 } else { |
| 1096 if (m_pType3Char) { | 1108 CPDF_Array* pContent = |
| 1097 m_pType3Char->m_bColored = m_pParser->IsColored(); | 1109 m_pObjects->m_pFormDict->GetArray(FX_BSTRC("Contents")); |
| 1098 m_pType3Char->m_Width = FXSYS_round(m_pParser->GetType3Data()[0]
* 1000); | 1110 m_pStreamArray[m_CurrentOffset] = new CPDF_StreamAcc; |
| 1099 m_pType3Char->m_BBox.left = FXSYS_round(m_pParser->GetType3Data(
)[2] * 1000); | 1111 CPDF_Stream* pStreamObj = |
| 1100 m_pType3Char->m_BBox.bottom = FXSYS_round(m_pParser->GetType3Dat
a()[3] * 1000); | 1112 (CPDF_Stream*)(pContent ? pContent->GetElementValue(m_CurrentOffset) |
| 1101 m_pType3Char->m_BBox.right = FXSYS_round(m_pParser->GetType3Data
()[4] * 1000); | 1113 : NULL); |
| 1102 m_pType3Char->m_BBox.top = FXSYS_round(m_pParser->GetType3Data()
[5] * 1000); | 1114 m_pStreamArray[m_CurrentOffset]->LoadAllData(pStreamObj, FALSE); |
| 1103 } | 1115 m_CurrentOffset++; |
| 1104 FX_POSITION pos = m_pObjects->m_ObjectList.GetHeadPosition(); | 1116 } |
| 1105 while (pos) { | 1117 } |
| 1106 CPDF_PageObject* pObj = (CPDF_PageObject*)m_pObjects->m_ObjectLi
st.GetNext(pos); | 1118 if (m_InternalStage == PAGEPARSE_STAGE_PARSE) { |
| 1107 if (pObj->m_ClipPath.IsNull()) { | 1119 if (!m_pParser) { |
| 1108 continue; | 1120 m_pParser = new CPDF_StreamContentParser( |
| 1109 } | 1121 m_pObjects->m_pDocument, m_pObjects->m_pPageResources, nullptr, |
| 1110 if (pObj->m_ClipPath.GetPathCount() != 1) { | 1122 nullptr, m_pObjects, m_pObjects->m_pResources, &m_pObjects->m_BBox, |
| 1111 continue; | 1123 &m_Options, nullptr, 0); |
| 1112 } | 1124 m_pParser->GetCurStates()->m_ColorState.GetModify()->Default(); |
| 1113 if (pObj->m_ClipPath.GetTextCount()) { | 1125 } |
| 1114 continue; | 1126 if (m_CurrentOffset >= m_Size) { |
| 1115 } | 1127 m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP; |
| 1116 CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0); | 1128 } else { |
| 1117 if (!ClipPath.IsRect() || pObj->m_Type == PDFPAGE_SHADING) { | 1129 m_CurrentOffset += |
| 1118 continue; | 1130 m_pParser->Parse(m_pData + m_CurrentOffset, |
| 1119 } | 1131 m_Size - m_CurrentOffset, PARSE_STEP_LIMIT); |
| 1120 CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY
(0), | 1132 if (m_pParser->ShouldAbort()) { |
| 1121 ClipPath.GetPointX(2), ClipPath.GetPointY
(2)); | 1133 m_InternalStage = PAGEPARSE_STAGE_CHECKCLIP; |
| 1122 CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Rig
ht, pObj->m_Top); | 1134 continue; |
| 1123 if (old_rect.Contains(obj_rect)) { | 1135 } |
| 1124 pObj->m_ClipPath.SetNull(); | 1136 } |
| 1125 } | 1137 } |
| 1126 } | 1138 if (m_InternalStage == PAGEPARSE_STAGE_CHECKCLIP) { |
| 1127 m_Status = Done; | 1139 if (m_pType3Char) { |
| 1128 return; | 1140 m_pType3Char->m_bColored = m_pParser->IsColored(); |
| 1129 } | 1141 m_pType3Char->m_Width = |
| 1130 steps ++; | 1142 FXSYS_round(m_pParser->GetType3Data()[0] * 1000); |
| 1131 if (pPause && pPause->NeedToPauseNow()) { | 1143 m_pType3Char->m_BBox.left = |
| 1132 break; | 1144 FXSYS_round(m_pParser->GetType3Data()[2] * 1000); |
| 1133 } | 1145 m_pType3Char->m_BBox.bottom = |
| 1134 } | 1146 FXSYS_round(m_pParser->GetType3Data()[3] * 1000); |
| 1135 } | 1147 m_pType3Char->m_BBox.right = |
| 1148 FXSYS_round(m_pParser->GetType3Data()[4] * 1000); |
| 1149 m_pType3Char->m_BBox.top = |
| 1150 FXSYS_round(m_pParser->GetType3Data()[5] * 1000); |
| 1151 } |
| 1152 FX_POSITION pos = m_pObjects->m_ObjectList.GetHeadPosition(); |
| 1153 while (pos) { |
| 1154 CPDF_PageObject* pObj = |
| 1155 (CPDF_PageObject*)m_pObjects->m_ObjectList.GetNext(pos); |
| 1156 if (pObj->m_ClipPath.IsNull()) { |
| 1157 continue; |
| 1158 } |
| 1159 if (pObj->m_ClipPath.GetPathCount() != 1) { |
| 1160 continue; |
| 1161 } |
| 1162 if (pObj->m_ClipPath.GetTextCount()) { |
| 1163 continue; |
| 1164 } |
| 1165 CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0); |
| 1166 if (!ClipPath.IsRect() || pObj->m_Type == PDFPAGE_SHADING) { |
| 1167 continue; |
| 1168 } |
| 1169 CFX_FloatRect old_rect(ClipPath.GetPointX(0), ClipPath.GetPointY(0), |
| 1170 ClipPath.GetPointX(2), ClipPath.GetPointY(2)); |
| 1171 CFX_FloatRect obj_rect(pObj->m_Left, pObj->m_Bottom, pObj->m_Right, |
| 1172 pObj->m_Top); |
| 1173 if (old_rect.Contains(obj_rect)) { |
| 1174 pObj->m_ClipPath.SetNull(); |
| 1175 } |
| 1176 } |
| 1177 m_Status = Done; |
| 1178 return; |
| 1179 } |
| 1180 steps++; |
| 1181 if (pPause && pPause->NeedToPauseNow()) { |
| 1182 break; |
| 1183 } |
| 1184 } |
| 1185 } |
| OLD | NEW |