1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "../../../include/fpdfapi/fpdf_parser.h"
8 #include "../../../include/fxcrt/fx_string.h"
9
10 //static
11 int CPDF_Object::s_nCurRefDepth = 0;
12
Release()13 void CPDF_Object::Release()
14 {
15 if (m_ObjNum) {
16 return;
17 }
18 Destroy();
19 }
Destroy()20 void CPDF_Object::Destroy()
21 {
22 switch (m_Type) {
23 case PDFOBJ_STRING:
24 delete (CPDF_String*)this;
25 break;
26 case PDFOBJ_NAME:
27 delete (CPDF_Name*)this;
28 break;
29 case PDFOBJ_ARRAY:
30 delete (CPDF_Array*)this;
31 break;
32 case PDFOBJ_DICTIONARY:
33 delete (CPDF_Dictionary*)this;
34 break;
35 case PDFOBJ_STREAM:
36 delete (CPDF_Stream*)this;
37 break;
38 default:
39 delete this;
40 }
41 }
GetString() const42 CFX_ByteString CPDF_Object::GetString() const
43 {
44 switch (m_Type) {
45 case PDFOBJ_BOOLEAN:
46 return ((CPDF_Boolean*)this)->m_bValue ? "true" : "false";
47 case PDFOBJ_NUMBER:
48 return ((CPDF_Number*)this)->GetString();
49 case PDFOBJ_STRING:
50 return ((CPDF_String*)this)->m_String;
51 case PDFOBJ_NAME:
52 return ((CPDF_Name*)this)->m_Name;
53 case PDFOBJ_REFERENCE: {
54 CPDF_Reference* pRef = (CPDF_Reference*)(FX_LPVOID)this;
55 if (pRef->m_pObjList == NULL) {
56 break;
57 }
58 CPDF_Object* pObj = pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum);
59 if (pObj == NULL) {
60 return CFX_ByteString();
61 }
62 return pObj->GetString();
63 }
64 }
65 return CFX_ByteString();
66 }
GetConstString() const67 CFX_ByteStringC CPDF_Object::GetConstString() const
68 {
69 switch (m_Type) {
70 case PDFOBJ_STRING:
71 return CFX_ByteStringC((FX_LPCBYTE)((CPDF_String*)this)->m_String, ((CPDF_String*)this)->m_String.GetLength());
72 case PDFOBJ_NAME:
73 return CFX_ByteStringC((FX_LPCBYTE)((CPDF_Name*)this)->m_Name, ((CPDF_Name*)this)->m_Name.GetLength());
74 case PDFOBJ_REFERENCE: {
75 CPDF_Reference* pRef = (CPDF_Reference*)(FX_LPVOID)this;
76 if (pRef->m_pObjList == NULL) {
77 break;
78 }
79 CPDF_Object* pObj = pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum);
80 if (pObj == NULL) {
81 return CFX_ByteStringC();
82 }
83 return pObj->GetConstString();
84 }
85 }
86 return CFX_ByteStringC();
87 }
GetNumber() const88 FX_FLOAT CPDF_Object::GetNumber() const
89 {
90 switch (m_Type) {
91 case PDFOBJ_NUMBER:
92 return ((CPDF_Number*)this)->GetNumber();
93 case PDFOBJ_REFERENCE: {
94 CPDF_Reference* pRef = (CPDF_Reference*)(FX_LPVOID)this;
95 if (pRef->m_pObjList == NULL) {
96 break;
97 }
98 CPDF_Object* pObj = pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum);
99 if (pObj == NULL) {
100 return 0;
101 }
102 return pObj->GetNumber();
103 }
104 }
105 return 0;
106 }
GetNumber16() const107 FX_FLOAT CPDF_Object::GetNumber16() const
108 {
109 return GetNumber();
110 }
GetInteger() const111 int CPDF_Object::GetInteger() const
112 {
113 CFX_AutoRestorer<int> restorer(&s_nCurRefDepth);
114 if (++s_nCurRefDepth > OBJECT_REF_MAX_DEPTH) {
115 return 0;
116 }
117 switch (m_Type) {
118 case PDFOBJ_BOOLEAN:
119 return ((CPDF_Boolean*)this)->m_bValue;
120 case PDFOBJ_NUMBER:
121 return ((CPDF_Number*)this)->GetInteger();
122 case PDFOBJ_REFERENCE: {
123 CPDF_Reference* pRef = (CPDF_Reference*)(FX_LPVOID)this;
124 PARSE_CONTEXT context;
125 FXSYS_memset32(&context, 0, sizeof(PARSE_CONTEXT));
126 if (pRef->m_pObjList == NULL) {
127 return 0;
128 }
129 CPDF_Object* pObj = pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum, &context);
130 if (pObj == NULL) {
131 return 0;
132 }
133 return pObj->GetInteger();
134 }
135 }
136 return 0;
137 }
GetDict() const138 CPDF_Dictionary* CPDF_Object::GetDict() const
139 {
140 switch (m_Type) {
141 case PDFOBJ_DICTIONARY:
142 return (CPDF_Dictionary*)this;
143 case PDFOBJ_STREAM:
144 return ((CPDF_Stream*)this)->GetDict();
145 case PDFOBJ_REFERENCE: {
146 CPDF_Reference* pRef = (CPDF_Reference*)this;
147 if (pRef->m_pObjList == NULL) {
148 break;
149 }
150 CPDF_Object* pObj = pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum);
151 if (pObj == NULL) {
152 return NULL;
153 }
154 return pObj->GetDict();
155 }
156 }
157 return NULL;
158 }
GetArray() const159 CPDF_Array* CPDF_Object::GetArray() const
160 {
161 if (m_Type == PDFOBJ_ARRAY)
162 return (CPDF_Array*)this;
163 else
164 return NULL;
165 }
SetString(const CFX_ByteString & str)166 void CPDF_Object::SetString(const CFX_ByteString& str)
167 {
168 ASSERT(this != NULL);
169 switch (m_Type) {
170 case PDFOBJ_BOOLEAN:
171 ((CPDF_Boolean*)this)->m_bValue = str == FX_BSTRC("true") ? 1 : 0;
172 return;
173 case PDFOBJ_NUMBER:
174 ((CPDF_Number*)this)->SetString(str);
175 return;
176 case PDFOBJ_STRING:
177 ((CPDF_String*)this)->m_String = str;
178 return;
179 case PDFOBJ_NAME:
180 ((CPDF_Name*)this)->m_Name = str;
181 return;
182 }
183 ASSERT(FALSE);
184 }
GetDirectType() const185 int CPDF_Object::GetDirectType() const
186 {
187 if (m_Type != PDFOBJ_REFERENCE) {
188 return m_Type;
189 }
190 CPDF_Reference* pRef = (CPDF_Reference*)this;
191 return pRef->m_pObjList->GetIndirectType(pRef->m_RefObjNum);
192 }
IsIdentical(CPDF_Object * pOther) const193 FX_BOOL CPDF_Object::IsIdentical(CPDF_Object* pOther) const
194 {
195 if (this == pOther) {
196 return TRUE;
197 }
198 if (pOther == NULL) {
199 return FALSE;
200 }
201 if (pOther->m_Type != m_Type) {
202 if (m_Type == PDFOBJ_REFERENCE && GetDirect()) {
203 return GetDirect()->IsIdentical(pOther);
204 } else if (pOther->m_Type == PDFOBJ_REFERENCE) {
205 return IsIdentical(pOther->GetDirect());
206 }
207 return FALSE;
208 }
209 switch (m_Type) {
210 case PDFOBJ_BOOLEAN:
211 return (((CPDF_Boolean*)this)->Identical((CPDF_Boolean*)pOther));
212 case PDFOBJ_NUMBER:
213 return (((CPDF_Number*)this)->Identical((CPDF_Number*)pOther));
214 case PDFOBJ_STRING:
215 return (((CPDF_String*)this)->Identical((CPDF_String*)pOther));
216 case PDFOBJ_NAME:
217 return (((CPDF_Name*)this)->Identical((CPDF_Name*)pOther));
218 case PDFOBJ_ARRAY:
219 return (((CPDF_Array*)this)->Identical((CPDF_Array*)pOther));
220 case PDFOBJ_DICTIONARY:
221 return (((CPDF_Dictionary*)this)->Identical((CPDF_Dictionary*)pOther));
222 case PDFOBJ_NULL:
223 return TRUE;
224 case PDFOBJ_STREAM:
225 return (((CPDF_Stream*)this)->Identical((CPDF_Stream*)pOther));
226 case PDFOBJ_REFERENCE:
227 return (((CPDF_Reference*)this)->Identical((CPDF_Reference*)pOther));
228 }
229 return FALSE;
230 }
GetDirect() const231 CPDF_Object* CPDF_Object::GetDirect() const
232 {
233 if (m_Type != PDFOBJ_REFERENCE) {
234 return (CPDF_Object*)this;
235 }
236 CPDF_Reference* pRef = (CPDF_Reference*)(FX_LPVOID)this;
237 if (pRef->m_pObjList == NULL) {
238 return NULL;
239 }
240 return pRef->m_pObjList->GetIndirectObject(pRef->m_RefObjNum);
241 }
Clone(FX_BOOL bDirect) const242 CPDF_Object* CPDF_Object::Clone(FX_BOOL bDirect) const
243 {
244 CFX_MapPtrToPtr visited;
245 return CloneInternal(bDirect, &visited);
246 }
CloneInternal(FX_BOOL bDirect,CFX_MapPtrToPtr * visited) const247 CPDF_Object* CPDF_Object::CloneInternal(FX_BOOL bDirect, CFX_MapPtrToPtr* visited) const
248 {
249 switch (m_Type) {
250 case PDFOBJ_BOOLEAN:
251 return new CPDF_Boolean(((CPDF_Boolean*)this)->m_bValue);
252 case PDFOBJ_NUMBER:
253 return new CPDF_Number(((CPDF_Number*)this)->m_bInteger, &((CPDF_Number*)this)->m_Integer);
254 case PDFOBJ_STRING:
255 return new CPDF_String(((CPDF_String*)this)->m_String, ((CPDF_String*)this)->IsHex());
256 case PDFOBJ_NAME:
257 return new CPDF_Name(((CPDF_Name*)this)->m_Name);
258 case PDFOBJ_ARRAY: {
259 CPDF_Array* pCopy = new CPDF_Array();
260 CPDF_Array* pThis = (CPDF_Array*)this;
261 int n = pThis->GetCount();
262 for (int i = 0; i < n; i ++) {
263 CPDF_Object* value = (CPDF_Object*)pThis->m_Objects.GetAt(i);
264 pCopy->m_Objects.Add(value->CloneInternal(bDirect, visited));
265 }
266 return pCopy;
267 }
268 case PDFOBJ_DICTIONARY: {
269 CPDF_Dictionary* pCopy = new CPDF_Dictionary();
270 CPDF_Dictionary* pThis = (CPDF_Dictionary*)this;
271 FX_POSITION pos = pThis->m_Map.GetStartPosition();
272 while (pos) {
273 CFX_ByteString key;
274 CPDF_Object* value;
275 pThis->m_Map.GetNextAssoc(pos, key, (void*&)value);
276 pCopy->m_Map.SetAt(key, value->CloneInternal(bDirect, visited));
277 }
278 return pCopy;
279 }
280 case PDFOBJ_NULL: {
281 return new CPDF_Null;
282 }
283 case PDFOBJ_STREAM: {
284 CPDF_Stream* pThis = (CPDF_Stream*)this;
285 CPDF_StreamAcc acc;
286 acc.LoadAllData(pThis, TRUE);
287 FX_DWORD streamSize = acc.GetSize();
288 CPDF_Stream* pObj;
289 if (pThis->GetDict())
290 pObj = new CPDF_Stream(acc.DetachData(), streamSize, (CPDF_Dictionary*)((CPDF_Object*)pThis->GetDict())->CloneInternal(bDirect, visited));
291 else
292 pObj = new CPDF_Stream(acc.DetachData(), streamSize, NULL);
293 return pObj;
294 }
295 case PDFOBJ_REFERENCE: {
296 CPDF_Reference* pRef = (CPDF_Reference*)this;
297 FX_DWORD obj_num = pRef->m_RefObjNum;
298 if (bDirect && !visited->GetValueAt((void*)(FX_UINTPTR)obj_num)) {
299 visited->SetAt((void*)(FX_UINTPTR)obj_num, (void*)1);
300 CPDF_Object* ret;
301 if (pRef->GetDirect())
302 ret = pRef->GetDirect()->CloneInternal(TRUE, visited);
303 else
304 ret = NULL;
305 return ret;
306 } else {
307 return new CPDF_Reference(pRef->m_pObjList, obj_num);
308 }
309 }
310 }
311 return NULL;
312 }
CloneRef(CPDF_IndirectObjects * pDoc) const313 CPDF_Object* CPDF_Object::CloneRef(CPDF_IndirectObjects* pDoc) const
314 {
315 if (m_ObjNum) {
316 return new CPDF_Reference(pDoc, m_ObjNum);
317 }
318 return Clone();
319 }
GetUnicodeText(CFX_CharMap * pCharMap) const320 CFX_WideString CPDF_Object::GetUnicodeText(CFX_CharMap* pCharMap) const
321 {
322 if (m_Type == PDFOBJ_STRING) {
323 return PDF_DecodeText(((CPDF_String*)this)->m_String, pCharMap);
324 } else if (m_Type == PDFOBJ_STREAM) {
325 CPDF_StreamAcc stream;
326 stream.LoadAllData((CPDF_Stream*)this, FALSE);
327 CFX_WideString result = PDF_DecodeText(stream.GetData(), stream.GetSize(), pCharMap);
328 return result;
329 } else if (m_Type == PDFOBJ_NAME) {
330 return PDF_DecodeText(((CPDF_Name*)this)->m_Name, pCharMap);
331 }
332 return CFX_WideString();
333 }
SetUnicodeText(FX_LPCWSTR pUnicodes,int len)334 void CPDF_Object::SetUnicodeText(FX_LPCWSTR pUnicodes, int len)
335 {
336 if (m_Type == PDFOBJ_STRING) {
337 ((CPDF_String*)this)->m_String = PDF_EncodeText(pUnicodes, len);
338 } else if (m_Type == PDFOBJ_STREAM) {
339 CFX_ByteString result = PDF_EncodeText(pUnicodes, len);
340 ((CPDF_Stream*)this)->SetData((FX_LPBYTE)result.c_str(), result.GetLength(), FALSE, FALSE);
341 }
342 }
343
CPDF_Number(int value)344 CPDF_Number::CPDF_Number(int value)
345 : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(TRUE), m_Integer(value) {
346 }
347
CPDF_Number(FX_FLOAT value)348 CPDF_Number::CPDF_Number(FX_FLOAT value)
349 : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(FALSE), m_Float(value) {
350 }
351
CPDF_Number(FX_BOOL bInteger,void * pData)352 CPDF_Number::CPDF_Number(FX_BOOL bInteger, void* pData)
353 : CPDF_Object(PDFOBJ_NUMBER), m_bInteger(bInteger), m_Integer(*(int*)pData) {
354 }
355
CPDF_Number(FX_BSTR str)356 CPDF_Number::CPDF_Number(FX_BSTR str) : CPDF_Object(PDFOBJ_NUMBER) {
357 FX_atonum(str, m_bInteger, &m_Integer);
358 }
359
SetString(FX_BSTR str)360 void CPDF_Number::SetString(FX_BSTR str)
361 {
362 FX_atonum(str, m_bInteger, &m_Integer);
363 }
Identical(CPDF_Number * pOther) const364 FX_BOOL CPDF_Number::Identical(CPDF_Number* pOther) const
365 {
366 return m_bInteger == pOther->m_bInteger && m_Integer == pOther->m_Integer;
367 }
GetString() const368 CFX_ByteString CPDF_Number::GetString() const
369 {
370 return m_bInteger ? CFX_ByteString::FormatInteger(m_Integer, FXFORMAT_SIGNED) : CFX_ByteString::FormatFloat(m_Float);
371 }
SetNumber(FX_FLOAT value)372 void CPDF_Number::SetNumber(FX_FLOAT value)
373 {
374 m_bInteger = FALSE;
375 m_Float = value;
376 }
CPDF_String(const CFX_WideString & str)377 CPDF_String::CPDF_String(const CFX_WideString& str) : CPDF_Object(PDFOBJ_STRING), m_bHex(FALSE) {
378 m_String = PDF_EncodeText(str);
379 }
~CPDF_Array()380 CPDF_Array::~CPDF_Array()
381 {
382 int size = m_Objects.GetSize();
383 CPDF_Object** pList = (CPDF_Object**)m_Objects.GetData();
384 for (int i = 0; i < size; i ++) {
385 if (pList[i])
386 pList[i]->Release();
387 }
388 }
GetRect()389 CFX_FloatRect CPDF_Array::GetRect()
390 {
391 CFX_FloatRect rect;
392 if (m_Type != PDFOBJ_ARRAY || m_Objects.GetSize() != 4) {
393 return rect;
394 }
395 rect.left = GetNumber(0);
396 rect.bottom = GetNumber(1);
397 rect.right = GetNumber(2);
398 rect.top = GetNumber(3);
399 return rect;
400 }
GetMatrix()401 CFX_AffineMatrix CPDF_Array::GetMatrix()
402 {
403 CFX_AffineMatrix matrix;
404 if (m_Type != PDFOBJ_ARRAY || m_Objects.GetSize() != 6) {
405 return matrix;
406 }
407 matrix.Set(GetNumber(0), GetNumber(1), GetNumber(2), GetNumber(3), GetNumber(4), GetNumber(5));
408 return matrix;
409 }
GetElement(FX_DWORD i) const410 CPDF_Object* CPDF_Array::GetElement(FX_DWORD i) const
411 {
412 if (i >= (FX_DWORD)m_Objects.GetSize()) {
413 return NULL;
414 }
415 return (CPDF_Object*)m_Objects.GetAt(i);
416 }
GetElementValue(FX_DWORD i) const417 CPDF_Object* CPDF_Array::GetElementValue(FX_DWORD i) const
418 {
419 if (i >= (FX_DWORD)m_Objects.GetSize()) {
420 return NULL;
421 }
422 return ((CPDF_Object*)m_Objects.GetAt(i))->GetDirect();
423 }
GetString(FX_DWORD i) const424 CFX_ByteString CPDF_Array::GetString(FX_DWORD i) const
425 {
426 if (i < (FX_DWORD)m_Objects.GetSize()) {
427 CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i);
428 return p->GetString();
429 }
430 else
431 return CFX_ByteString();
432 }
GetConstString(FX_DWORD i) const433 CFX_ByteStringC CPDF_Array::GetConstString(FX_DWORD i) const
434 {
435 if (i < (FX_DWORD)m_Objects.GetSize()) {
436 CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i);
437 return p->GetConstString();
438 }
439 else
440 return CFX_ByteStringC();
441 }
GetInteger(FX_DWORD i) const442 int CPDF_Array::GetInteger(FX_DWORD i) const
443 {
444 if (i >= (FX_DWORD)m_Objects.GetSize()) {
445 return 0;
446 }
447 CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i);
448 return p->GetInteger();
449 }
GetNumber(FX_DWORD i) const450 FX_FLOAT CPDF_Array::GetNumber(FX_DWORD i) const
451 {
452 if (i >= (FX_DWORD)m_Objects.GetSize()) {
453 return 0;
454 }
455 CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i);
456 return p->GetNumber();
457 }
GetDict(FX_DWORD i) const458 CPDF_Dictionary* CPDF_Array::GetDict(FX_DWORD i) const
459 {
460 CPDF_Object* p = GetElementValue(i);
461 if (p == NULL) {
462 return NULL;
463 } else if (p->GetType() == PDFOBJ_DICTIONARY) {
464 return (CPDF_Dictionary*)p;
465 } else if (p->GetType() == PDFOBJ_STREAM) {
466 return ((CPDF_Stream*)p)->GetDict();
467 }
468 return NULL;
469 }
GetStream(FX_DWORD i) const470 CPDF_Stream* CPDF_Array::GetStream(FX_DWORD i) const
471 {
472 CPDF_Object* p = GetElementValue(i);
473 if (p == NULL || p->GetType() != PDFOBJ_STREAM) {
474 return NULL;
475 }
476 return (CPDF_Stream*)p;
477 }
GetArray(FX_DWORD i) const478 CPDF_Array* CPDF_Array::GetArray(FX_DWORD i) const
479 {
480 CPDF_Object* p = GetElementValue(i);
481 if (p == NULL || p->GetType() != PDFOBJ_ARRAY) {
482 return NULL;
483 }
484 return (CPDF_Array*)p;
485 }
RemoveAt(FX_DWORD i)486 void CPDF_Array::RemoveAt(FX_DWORD i)
487 {
488 ASSERT(m_Type == PDFOBJ_ARRAY);
489 if (i >= (FX_DWORD)m_Objects.GetSize()) {
490 return;
491 }
492 CPDF_Object* p = (CPDF_Object*)m_Objects.GetAt(i);
493 if (p)
494 p->Release();
495 m_Objects.RemoveAt(i);
496 }
SetAt(FX_DWORD i,CPDF_Object * pObj,CPDF_IndirectObjects * pObjs)497 void CPDF_Array::SetAt(FX_DWORD i, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs)
498 {
499 ASSERT(m_Type == PDFOBJ_ARRAY);
500 ASSERT(i < (FX_DWORD)m_Objects.GetSize());
501 if (i >= (FX_DWORD)m_Objects.GetSize()) {
502 return;
503 }
504 CPDF_Object* pOld = (CPDF_Object*)m_Objects.GetAt(i);
505 if (pOld)
506 pOld->Release();
507 if (pObj->GetObjNum()) {
508 ASSERT(pObjs != NULL);
509 pObj = CPDF_Reference::Create(pObjs, pObj->GetObjNum());
510 }
511 m_Objects.SetAt(i, pObj);
512 }
InsertAt(FX_DWORD index,CPDF_Object * pObj,CPDF_IndirectObjects * pObjs)513 void CPDF_Array::InsertAt(FX_DWORD index, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs)
514 {
515 ASSERT(pObj != NULL);
516 if (pObj->GetObjNum()) {
517 ASSERT(pObjs != NULL);
518 pObj = CPDF_Reference::Create(pObjs, pObj->GetObjNum());
519 }
520 m_Objects.InsertAt(index, pObj);
521 }
Add(CPDF_Object * pObj,CPDF_IndirectObjects * pObjs)522 void CPDF_Array::Add(CPDF_Object* pObj, CPDF_IndirectObjects* pObjs)
523 {
524 ASSERT(pObj != NULL);
525 if (pObj->GetObjNum()) {
526 ASSERT(pObjs != NULL);
527 pObj = CPDF_Reference::Create(pObjs, pObj->GetObjNum());
528 }
529 m_Objects.Add(pObj);
530 }
AddName(const CFX_ByteString & str)531 void CPDF_Array::AddName(const CFX_ByteString& str)
532 {
533 ASSERT(m_Type == PDFOBJ_ARRAY);
534 Add(new CPDF_Name(str));
535 }
AddString(const CFX_ByteString & str)536 void CPDF_Array::AddString(const CFX_ByteString& str)
537 {
538 ASSERT(m_Type == PDFOBJ_ARRAY);
539 Add(new CPDF_String(str));
540 }
AddInteger(int i)541 void CPDF_Array::AddInteger(int i)
542 {
543 ASSERT(m_Type == PDFOBJ_ARRAY);
544 Add(new CPDF_Number(i));
545 }
AddNumber(FX_FLOAT f)546 void CPDF_Array::AddNumber(FX_FLOAT f)
547 {
548 ASSERT(m_Type == PDFOBJ_ARRAY);
549 CPDF_Number* pNumber = new CPDF_Number;
550 pNumber->SetNumber(f);
551 Add(pNumber);
552 }
AddReference(CPDF_IndirectObjects * pDoc,FX_DWORD objnum)553 void CPDF_Array::AddReference(CPDF_IndirectObjects* pDoc, FX_DWORD objnum)
554 {
555 ASSERT(m_Type == PDFOBJ_ARRAY);
556 Add(new CPDF_Reference(pDoc, objnum));
557 }
Identical(CPDF_Array * pOther) const558 FX_BOOL CPDF_Array::Identical(CPDF_Array* pOther) const
559 {
560 if (m_Objects.GetSize() != pOther->m_Objects.GetSize()) {
561 return FALSE;
562 }
563 for (int i = 0; i < m_Objects.GetSize(); i ++)
564 if (!((CPDF_Object*)m_Objects[i])->IsIdentical((CPDF_Object*)pOther->m_Objects[i])) {
565 return FALSE;
566 }
567 return TRUE;
568 }
~CPDF_Dictionary()569 CPDF_Dictionary::~CPDF_Dictionary()
570 {
571 FX_POSITION pos = m_Map.GetStartPosition();
572 while (pos) {
573 FX_LPVOID value = m_Map.GetNextValue(pos);
574 if (value)
575 ((CPDF_Object*)value)->Release();
576 }
577 }
GetStartPos() const578 FX_POSITION CPDF_Dictionary::GetStartPos() const
579 {
580 return m_Map.GetStartPosition();
581 }
GetNextElement(FX_POSITION & pos,CFX_ByteString & key) const582 CPDF_Object* CPDF_Dictionary::GetNextElement(FX_POSITION& pos, CFX_ByteString& key) const
583 {
584 if (pos == NULL) {
585 return NULL;
586 }
587 CPDF_Object* p;
588 m_Map.GetNextAssoc(pos, key, (FX_LPVOID&)p);
589 return p;
590 }
GetElement(FX_BSTR key) const591 CPDF_Object* CPDF_Dictionary::GetElement(FX_BSTR key) const
592 {
593 CPDF_Object* p = NULL;
594 m_Map.Lookup(key, (void*&)p);
595 return p;
596 }
GetElementValue(FX_BSTR key) const597 CPDF_Object* CPDF_Dictionary::GetElementValue(FX_BSTR key) const
598 {
599 CPDF_Object* p = NULL;
600 m_Map.Lookup(key, (void*&)p);
601 return p ? p->GetDirect() : NULL;
602 }
GetString(FX_BSTR key) const603 CFX_ByteString CPDF_Dictionary::GetString(FX_BSTR key) const
604 {
605 CPDF_Object* p = NULL;
606 m_Map.Lookup(key, (void*&)p);
607 if (p)
608 return p->GetString();
609 else
610 return CFX_ByteString();
611 }
GetConstString(FX_BSTR key) const612 CFX_ByteStringC CPDF_Dictionary::GetConstString(FX_BSTR key) const
613 {
614 CPDF_Object* p = NULL;
615 m_Map.Lookup(key, (void*&)p);
616 if (p)
617 return p->GetConstString();
618 else
619 return CFX_ByteStringC();
620 }
GetUnicodeText(FX_BSTR key,CFX_CharMap * pCharMap) const621 CFX_WideString CPDF_Dictionary::GetUnicodeText(FX_BSTR key, CFX_CharMap* pCharMap) const
622 {
623 CPDF_Object* p = NULL;
624 m_Map.Lookup(key, (void*&)p);
625 if (p) {
626 if(p->GetType() == PDFOBJ_REFERENCE) {
627 p = ((CPDF_Reference*)p)->GetDirect();
628 if (p) {
629 return p->GetUnicodeText(pCharMap);
630 }
631 } else {
632 return p->GetUnicodeText(pCharMap);
633 }
634 }
635 return CFX_WideString();
636 }
GetString(FX_BSTR key,FX_BSTR def) const637 CFX_ByteString CPDF_Dictionary::GetString(FX_BSTR key, FX_BSTR def) const
638 {
639 CPDF_Object* p = NULL;
640 m_Map.Lookup(key, (void*&)p);
641 if (p) {
642 return p->GetString();
643 }
644 return CFX_ByteString(def);
645 }
GetConstString(FX_BSTR key,FX_BSTR def) const646 CFX_ByteStringC CPDF_Dictionary::GetConstString(FX_BSTR key, FX_BSTR def) const
647 {
648 CPDF_Object* p = NULL;
649 m_Map.Lookup(key, (void*&)p);
650 if (p)
651 return p->GetConstString();
652 else
653 return CFX_ByteStringC(def);
654 }
GetInteger(FX_BSTR key) const655 int CPDF_Dictionary::GetInteger(FX_BSTR key) const
656 {
657 CPDF_Object* p = NULL;
658 m_Map.Lookup(key, (void*&)p);
659 if (p) {
660 return p->GetInteger();
661 }
662 return 0;
663 }
GetInteger(FX_BSTR key,int def) const664 int CPDF_Dictionary::GetInteger(FX_BSTR key, int def) const
665 {
666 CPDF_Object* p = NULL;
667 m_Map.Lookup(key, (void*&)p);
668 if (p) {
669 return p->GetInteger();
670 }
671 return def;
672 }
GetNumber(FX_BSTR key) const673 FX_FLOAT CPDF_Dictionary::GetNumber(FX_BSTR key) const
674 {
675 CPDF_Object* p = NULL;
676 m_Map.Lookup(key, (void*&)p);
677 if (p) {
678 return p->GetNumber();
679 }
680 return 0;
681 }
GetBoolean(FX_BSTR key,FX_BOOL bDefault) const682 FX_BOOL CPDF_Dictionary::GetBoolean(FX_BSTR key, FX_BOOL bDefault) const
683 {
684 CPDF_Object* p = NULL;
685 m_Map.Lookup(key, (void*&)p);
686 if (p && p->GetType() == PDFOBJ_BOOLEAN) {
687 return p->GetInteger();
688 }
689 return bDefault;
690 }
GetDict(FX_BSTR key) const691 CPDF_Dictionary* CPDF_Dictionary::GetDict(FX_BSTR key) const
692 {
693 CPDF_Object* p = GetElementValue(key);
694 if (p == NULL) {
695 return NULL;
696 } else if (p->GetType() == PDFOBJ_DICTIONARY) {
697 return (CPDF_Dictionary*)p;
698 } else if (p->GetType() == PDFOBJ_STREAM) {
699 return ((CPDF_Stream*)p)->GetDict();
700 }
701 return NULL;
702 }
GetArray(FX_BSTR key) const703 CPDF_Array* CPDF_Dictionary::GetArray(FX_BSTR key) const
704 {
705 CPDF_Object* p = GetElementValue(key);
706 if (p == NULL || p->GetType() != PDFOBJ_ARRAY) {
707 return NULL;
708 }
709 return (CPDF_Array*)p;
710 }
GetStream(FX_BSTR key) const711 CPDF_Stream* CPDF_Dictionary::GetStream(FX_BSTR key) const
712 {
713 CPDF_Object* p = GetElementValue(key);
714 if (p == NULL || p->GetType() != PDFOBJ_STREAM) {
715 return NULL;
716 }
717 return (CPDF_Stream*)p;
718 }
GetRect(FX_BSTR key) const719 CFX_FloatRect CPDF_Dictionary::GetRect(FX_BSTR key) const
720 {
721 CFX_FloatRect rect;
722 CPDF_Array* pArray = GetArray(key);
723 if (pArray) {
724 rect = pArray->GetRect();
725 }
726 return rect;
727 }
GetMatrix(FX_BSTR key) const728 CFX_AffineMatrix CPDF_Dictionary::GetMatrix(FX_BSTR key) const
729 {
730 CFX_AffineMatrix matrix;
731 CPDF_Array* pArray = GetArray(key);
732 if (pArray) {
733 matrix = pArray->GetMatrix();
734 }
735 return matrix;
736 }
KeyExist(FX_BSTR key) const737 FX_BOOL CPDF_Dictionary::KeyExist(FX_BSTR key) const
738 {
739 FX_LPVOID value;
740 return m_Map.Lookup(key, value);
741 }
SetAt(FX_BSTR key,CPDF_Object * pObj,CPDF_IndirectObjects * pObjs)742 void CPDF_Dictionary::SetAt(FX_BSTR key, CPDF_Object* pObj, CPDF_IndirectObjects* pObjs)
743 {
744 ASSERT(m_Type == PDFOBJ_DICTIONARY);
745 CPDF_Object* p = NULL;
746 m_Map.Lookup(key, (void*&)p);
747 if (p == pObj) {
748 return;
749 }
750 if (p)
751 p->Release();
752 if (pObj) {
753 if (pObj->GetObjNum()) {
754 ASSERT(pObjs != NULL);
755 pObj = CPDF_Reference::Create(pObjs, pObj->GetObjNum());
756 }
757 m_Map.SetAt(key, pObj);
758 } else {
759 m_Map.RemoveKey(key);
760 }
761 }
AddValue(FX_BSTR key,CPDF_Object * pObj)762 void CPDF_Dictionary::AddValue(FX_BSTR key, CPDF_Object* pObj)
763 {
764 ASSERT(m_Type == PDFOBJ_DICTIONARY);
765 m_Map.AddValue(key, pObj);
766 }
RemoveAt(FX_BSTR key)767 void CPDF_Dictionary::RemoveAt(FX_BSTR key)
768 {
769 ASSERT(m_Type == PDFOBJ_DICTIONARY);
770 CPDF_Object* p = NULL;
771 m_Map.Lookup(key, (void*&)p);
772 if (p == NULL) {
773 return;
774 }
775 p->Release();
776 m_Map.RemoveKey(key);
777 }
ReplaceKey(FX_BSTR oldkey,FX_BSTR newkey)778 void CPDF_Dictionary::ReplaceKey(FX_BSTR oldkey, FX_BSTR newkey)
779 {
780 ASSERT(m_Type == PDFOBJ_DICTIONARY);
781 CPDF_Object* p = NULL;
782 m_Map.Lookup(oldkey, (void*&)p);
783 if (p == NULL) {
784 return;
785 }
786 m_Map.RemoveKey(oldkey);
787 m_Map.SetAt(newkey, p);
788 }
Identical(CPDF_Dictionary * pOther) const789 FX_BOOL CPDF_Dictionary::Identical(CPDF_Dictionary* pOther) const
790 {
791 if (pOther == NULL) {
792 return FALSE;
793 }
794 if (m_Map.GetCount() != pOther->m_Map.GetCount()) {
795 return FALSE;
796 }
797 FX_POSITION pos = m_Map.GetStartPosition();
798 while (pos) {
799 CFX_ByteString key;
800 FX_LPVOID value;
801 m_Map.GetNextAssoc(pos, key, value);
802 if (!value)
803 return FALSE;
804 if (!((CPDF_Object*)value)->IsIdentical(pOther->GetElement(key))) {
805 return FALSE;
806 }
807 }
808 return TRUE;
809 }
SetAtInteger(FX_BSTR key,int i)810 void CPDF_Dictionary::SetAtInteger(FX_BSTR key, int i)
811 {
812 SetAt(key, new CPDF_Number(i));
813 }
SetAtName(FX_BSTR key,const CFX_ByteString & name)814 void CPDF_Dictionary::SetAtName(FX_BSTR key, const CFX_ByteString& name)
815 {
816 SetAt(key, new CPDF_Name(name));
817 }
SetAtString(FX_BSTR key,const CFX_ByteString & str)818 void CPDF_Dictionary::SetAtString(FX_BSTR key, const CFX_ByteString& str)
819 {
820 SetAt(key, new CPDF_String(str));
821 }
SetAtReference(FX_BSTR key,CPDF_IndirectObjects * pDoc,FX_DWORD objnum)822 void CPDF_Dictionary::SetAtReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, FX_DWORD objnum)
823 {
824 SetAt(key, new CPDF_Reference(pDoc, objnum));
825 }
AddReference(FX_BSTR key,CPDF_IndirectObjects * pDoc,FX_DWORD objnum)826 void CPDF_Dictionary::AddReference(FX_BSTR key, CPDF_IndirectObjects* pDoc, FX_DWORD objnum)
827 {
828 AddValue(key, new CPDF_Reference(pDoc, objnum));
829 }
SetAtNumber(FX_BSTR key,FX_FLOAT f)830 void CPDF_Dictionary::SetAtNumber(FX_BSTR key, FX_FLOAT f)
831 {
832 CPDF_Number* pNumber = new CPDF_Number;
833 pNumber->SetNumber(f);
834 SetAt(key, pNumber);
835 }
SetAtBoolean(FX_BSTR key,FX_BOOL bValue)836 void CPDF_Dictionary::SetAtBoolean(FX_BSTR key, FX_BOOL bValue)
837 {
838 SetAt(key, new CPDF_Boolean(bValue));
839 }
SetAtRect(FX_BSTR key,const CFX_FloatRect & rect)840 void CPDF_Dictionary::SetAtRect(FX_BSTR key, const CFX_FloatRect& rect)
841 {
842 CPDF_Array* pArray = new CPDF_Array;
843 pArray->AddNumber(rect.left);
844 pArray->AddNumber(rect.bottom);
845 pArray->AddNumber(rect.right);
846 pArray->AddNumber(rect.top);
847 SetAt(key, pArray);
848 }
SetAtMatrix(FX_BSTR key,const CFX_AffineMatrix & matrix)849 void CPDF_Dictionary::SetAtMatrix(FX_BSTR key, const CFX_AffineMatrix& matrix)
850 {
851 CPDF_Array* pArray = new CPDF_Array;
852 pArray->AddNumber16(matrix.a);
853 pArray->AddNumber16(matrix.b);
854 pArray->AddNumber16(matrix.c);
855 pArray->AddNumber16(matrix.d);
856 pArray->AddNumber(matrix.e);
857 pArray->AddNumber(matrix.f);
858 SetAt(key, pArray);
859 }
CPDF_Stream(FX_LPBYTE pData,FX_DWORD size,CPDF_Dictionary * pDict)860 CPDF_Stream::CPDF_Stream(FX_LPBYTE pData, FX_DWORD size, CPDF_Dictionary* pDict)
861 : CPDF_Object(PDFOBJ_STREAM) {
862 m_pDict = pDict;
863 m_dwSize = size;
864 m_GenNum = (FX_DWORD) - 1;
865 m_pDataBuf = pData;
866 m_pCryptoHandler = NULL;
867 }
~CPDF_Stream()868 CPDF_Stream::~CPDF_Stream()
869 {
870 if (m_GenNum == (FX_DWORD) - 1 && m_pDataBuf != NULL) {
871 FX_Free(m_pDataBuf);
872 }
873 if (m_pDict) {
874 m_pDict->Release();
875 }
876 }
InitStream(CPDF_Dictionary * pDict)877 void CPDF_Stream::InitStream(CPDF_Dictionary* pDict)
878 {
879 if (pDict) {
880 if (m_pDict) {
881 m_pDict->Release();
882 }
883 m_pDict = pDict;
884 }
885 if (m_GenNum == (FX_DWORD) - 1) {
886 if (m_pDataBuf) {
887 FX_Free(m_pDataBuf);
888 }
889 }
890 m_GenNum = 0;
891 m_pFile = NULL;
892 m_pCryptoHandler = NULL;
893 m_FileOffset = 0;
894 }
InitStream(FX_LPBYTE pData,FX_DWORD size,CPDF_Dictionary * pDict)895 void CPDF_Stream::InitStream(FX_LPBYTE pData, FX_DWORD size, CPDF_Dictionary* pDict)
896 {
897 InitStream(pDict);
898 m_GenNum = (FX_DWORD) - 1;
899 m_pDataBuf = FX_Alloc(FX_BYTE, size);
900 if (pData) {
901 FXSYS_memcpy32(m_pDataBuf, pData, size);
902 }
903 m_dwSize = size;
904 if (m_pDict) {
905 m_pDict->SetAtInteger(FX_BSTRC("Length"), size);
906 }
907 }
SetData(FX_LPCBYTE pData,FX_DWORD size,FX_BOOL bCompressed,FX_BOOL bKeepBuf)908 void CPDF_Stream::SetData(FX_LPCBYTE pData, FX_DWORD size, FX_BOOL bCompressed, FX_BOOL bKeepBuf)
909 {
910 if (m_GenNum == (FX_DWORD) - 1) {
911 if (m_pDataBuf) {
912 FX_Free(m_pDataBuf);
913 }
914 } else {
915 m_GenNum = (FX_DWORD) - 1;
916 m_pCryptoHandler = NULL;
917 }
918 if (bKeepBuf) {
919 m_pDataBuf = (FX_LPBYTE)pData;
920 } else {
921 m_pDataBuf = FX_Alloc(FX_BYTE, size);
922 if (pData) {
923 FXSYS_memcpy32(m_pDataBuf, pData, size);
924 }
925 }
926 m_dwSize = size;
927 if (m_pDict == NULL) {
928 m_pDict = new CPDF_Dictionary;
929 }
930 m_pDict->SetAtInteger(FX_BSTRC("Length"), size);
931 if (!bCompressed) {
932 m_pDict->RemoveAt(FX_BSTRC("Filter"));
933 m_pDict->RemoveAt(FX_BSTRC("DecodeParms"));
934 }
935 }
ReadRawData(FX_FILESIZE offset,FX_LPBYTE buf,FX_DWORD size) const936 FX_BOOL CPDF_Stream::ReadRawData(FX_FILESIZE offset, FX_LPBYTE buf, FX_DWORD size) const
937 {
938 if ((m_GenNum != (FX_DWORD) - 1) && m_pFile) {
939 return m_pFile->ReadBlock(buf, m_FileOffset + offset, size);
940 }
941 if (m_pDataBuf) {
942 FXSYS_memcpy32(buf, m_pDataBuf + offset, size);
943 }
944 return TRUE;
945 }
InitStream(IFX_FileRead * pFile,CPDF_Dictionary * pDict)946 void CPDF_Stream::InitStream(IFX_FileRead *pFile, CPDF_Dictionary* pDict)
947 {
948 InitStream(pDict);
949 m_pFile = pFile;
950 m_dwSize = (FX_DWORD)pFile->GetSize();
951 if (m_pDict) {
952 m_pDict->SetAtInteger(FX_BSTRC("Length"), m_dwSize);
953 }
954 }
Identical(CPDF_Stream * pOther) const955 FX_BOOL CPDF_Stream::Identical(CPDF_Stream* pOther) const
956 {
957 if (!m_pDict)
958 return pOther->m_pDict ? FALSE : TRUE;
959
960 if (!m_pDict->Identical(pOther->m_pDict)) {
961 return FALSE;
962 }
963 if (m_dwSize != pOther->m_dwSize) {
964 return FALSE;
965 }
966 if (m_GenNum != (FX_DWORD) - 1 && pOther->m_GenNum != (FX_DWORD) - 1) {
967 if (m_pFile == pOther->m_pFile && m_pFile == NULL) {
968 return TRUE;
969 }
970 if (!m_pFile || !pOther->m_pFile) {
971 return FALSE;
972 }
973 FX_BYTE srcBuf[1024];
974 FX_BYTE destBuf[1024];
975 FX_DWORD size = m_dwSize;
976 FX_DWORD srcOffset = m_FileOffset;
977 FX_DWORD destOffset = pOther->m_FileOffset;
978 if (m_pFile == pOther->m_pFile && srcOffset == destOffset) {
979 return TRUE;
980 }
981 while (size > 0) {
982 FX_DWORD actualSize = size > 1024 ? 1024 : size;
983 m_pFile->ReadBlock(srcBuf, srcOffset, actualSize);
984 pOther->m_pFile->ReadBlock(destBuf, destOffset, actualSize);
985 if (FXSYS_memcmp32(srcBuf, destBuf, actualSize) != 0) {
986 return FALSE;
987 }
988 size -= actualSize;
989 srcOffset += actualSize;
990 destOffset += actualSize;
991 }
992 return TRUE;
993 }
994 if (m_GenNum != (FX_DWORD) - 1 || pOther->m_GenNum != (FX_DWORD) - 1) {
995 IFX_FileRead* pFile = NULL;
996 FX_LPBYTE pBuf = NULL;
997 FX_DWORD offset = 0;
998 if (pOther->m_GenNum != (FX_DWORD) - 1) {
999 pFile = pOther->m_pFile;
1000 pBuf = m_pDataBuf;
1001 offset = pOther->m_FileOffset;
1002 } else if (m_GenNum != (FX_DWORD) - 1) {
1003 pFile = m_pFile;
1004 pBuf = pOther->m_pDataBuf;
1005 offset = m_FileOffset;
1006 }
1007 if (NULL == pBuf) {
1008 return FALSE;
1009 }
1010 FX_BYTE srcBuf[1024];
1011 FX_DWORD size = m_dwSize;
1012 while (size > 0) {
1013 FX_DWORD actualSize = std::min(size, 1024U);
1014 pFile->ReadBlock(srcBuf, offset, actualSize);
1015 if (FXSYS_memcmp32(srcBuf, pBuf, actualSize) != 0) {
1016 return FALSE;
1017 }
1018 pBuf += actualSize;
1019 size -= actualSize;
1020 offset += actualSize;
1021 }
1022 return TRUE;
1023 }
1024 return FXSYS_memcmp32(m_pDataBuf, pOther->m_pDataBuf, m_dwSize) == 0;
1025 }
Clone(FX_BOOL bDirect,FPDF_LPFCloneStreamCallback lpfCallback,FX_LPVOID pUserData) const1026 CPDF_Stream* CPDF_Stream::Clone(FX_BOOL bDirect, FPDF_LPFCloneStreamCallback lpfCallback, FX_LPVOID pUserData) const
1027 {
1028 CPDF_Dictionary *pCloneDict = (CPDF_Dictionary*)m_pDict->Clone(bDirect);
1029 IFX_FileStream *pFS = NULL;
1030 if (lpfCallback) {
1031 pFS = lpfCallback((CPDF_Stream*)this, pUserData);
1032 }
1033 if (!pFS) {
1034 CPDF_StreamAcc acc;
1035 acc.LoadAllData(this, TRUE);
1036 FX_DWORD streamSize = acc.GetSize();
1037 return new CPDF_Stream(acc.DetachData(), streamSize, pCloneDict);
1038 }
1039 CPDF_Stream* pObj = new CPDF_Stream(NULL, 0, NULL);
1040 CPDF_StreamFilter *pSF = GetStreamFilter(TRUE);
1041 if (pSF) {
1042 FX_LPBYTE pBuf = FX_Alloc(FX_BYTE, 4096);
1043 FX_DWORD dwRead;
1044 do {
1045 dwRead = pSF->ReadBlock(pBuf, 4096);
1046 if (dwRead) {
1047 pFS->WriteBlock(pBuf, dwRead);
1048 }
1049 } while (dwRead == 4096);
1050 pFS->Flush();
1051 FX_Free(pBuf);
1052 delete pSF;
1053 }
1054 pObj->InitStream((IFX_FileRead*)pFS, pCloneDict);
1055 return pObj;
1056 }
1057 extern FX_BOOL PDF_DataDecode(FX_LPCBYTE src_buf, FX_DWORD src_size, const CPDF_Dictionary* pDict,
1058 FX_LPBYTE& dest_buf, FX_DWORD& dest_size, CFX_ByteString& ImageEncoding,
1059 CPDF_Dictionary*& pImageParms, FX_DWORD estimated_size, FX_BOOL bImageAcc);
CPDF_StreamAcc()1060 CPDF_StreamAcc::CPDF_StreamAcc()
1061 {
1062 m_bNewBuf = FALSE;
1063 m_pData = NULL;
1064 m_dwSize = 0;
1065 m_pImageParam = NULL;
1066 m_pStream = NULL;
1067 m_pSrcData = NULL;
1068 }
LoadAllData(const CPDF_Stream * pStream,FX_BOOL bRawAccess,FX_DWORD estimated_size,FX_BOOL bImageAcc)1069 void CPDF_StreamAcc::LoadAllData(const CPDF_Stream* pStream, FX_BOOL bRawAccess, FX_DWORD estimated_size,
1070 FX_BOOL bImageAcc)
1071 {
1072 if (pStream == NULL || pStream->GetType() != PDFOBJ_STREAM) {
1073 return;
1074 }
1075 m_pStream = pStream;
1076 if (pStream->IsMemoryBased() &&
1077 (!pStream->GetDict()->KeyExist(FX_BSTRC("Filter")) || bRawAccess)) {
1078 m_dwSize = pStream->m_dwSize;
1079 m_pData = (FX_LPBYTE)pStream->m_pDataBuf;
1080 return;
1081 }
1082 FX_LPBYTE pSrcData;
1083 FX_DWORD dwSrcSize = pStream->m_dwSize;
1084 if (dwSrcSize == 0) {
1085 return;
1086 }
1087 if (!pStream->IsMemoryBased()) {
1088 pSrcData = m_pSrcData = FX_Alloc(FX_BYTE, dwSrcSize);
1089 if (!pStream->ReadRawData(0, pSrcData, dwSrcSize)) {
1090 return;
1091 }
1092 } else {
1093 pSrcData = pStream->m_pDataBuf;
1094 }
1095 FX_LPBYTE pDecryptedData;
1096 FX_DWORD dwDecryptedSize;
1097 if (pStream->m_pCryptoHandler) {
1098 CFX_BinaryBuf dest_buf;
1099 dest_buf.EstimateSize(pStream->m_pCryptoHandler->DecryptGetSize(dwSrcSize));
1100 FX_LPVOID context = pStream->m_pCryptoHandler->DecryptStart(pStream->GetObjNum(), pStream->m_GenNum);
1101 pStream->m_pCryptoHandler->DecryptStream(context, pSrcData, dwSrcSize, dest_buf);
1102 pStream->m_pCryptoHandler->DecryptFinish(context, dest_buf);
1103 pDecryptedData = dest_buf.GetBuffer();
1104 dwDecryptedSize = dest_buf.GetSize();
1105 dest_buf.DetachBuffer();
1106 } else {
1107 pDecryptedData = pSrcData;
1108 dwDecryptedSize = dwSrcSize;
1109 }
1110 if (!pStream->GetDict()->KeyExist(FX_BSTRC("Filter")) || bRawAccess) {
1111 m_pData = pDecryptedData;
1112 m_dwSize = dwDecryptedSize;
1113 } else {
1114 FX_BOOL bRet = PDF_DataDecode(pDecryptedData, dwDecryptedSize, m_pStream->GetDict(),
1115 m_pData, m_dwSize, m_ImageDecoder, m_pImageParam, estimated_size, bImageAcc);
1116 if (!bRet) {
1117 m_pData = pDecryptedData;
1118 m_dwSize = dwDecryptedSize;
1119 }
1120 }
1121 if (pSrcData != pStream->m_pDataBuf && pSrcData != m_pData) {
1122 FX_Free(pSrcData);
1123 }
1124 if (pDecryptedData != pSrcData && pDecryptedData != m_pData) {
1125 FX_Free(pDecryptedData);
1126 }
1127 m_pSrcData = NULL;
1128 m_bNewBuf = m_pData != pStream->m_pDataBuf;
1129 }
~CPDF_StreamAcc()1130 CPDF_StreamAcc::~CPDF_StreamAcc()
1131 {
1132 if (m_bNewBuf && m_pData) {
1133 FX_Free(m_pData);
1134 }
1135 if (m_pSrcData) {
1136 FX_Free(m_pSrcData);
1137 }
1138 }
GetData() const1139 FX_LPCBYTE CPDF_StreamAcc::GetData() const
1140 {
1141 if (m_bNewBuf) {
1142 return m_pData;
1143 }
1144 if (!m_pStream) {
1145 return NULL;
1146 }
1147 return m_pStream->m_pDataBuf;
1148 }
GetSize() const1149 FX_DWORD CPDF_StreamAcc::GetSize() const
1150 {
1151 if (m_bNewBuf) {
1152 return m_dwSize;
1153 }
1154 if (!m_pStream) {
1155 return 0;
1156 }
1157 return m_pStream->m_dwSize;
1158 }
DetachData()1159 FX_LPBYTE CPDF_StreamAcc::DetachData()
1160 {
1161 if (m_bNewBuf) {
1162 FX_LPBYTE p = m_pData;
1163 m_pData = NULL;
1164 m_dwSize = 0;
1165 return p;
1166 }
1167 FX_LPBYTE p = FX_Alloc(FX_BYTE, m_dwSize);
1168 FXSYS_memcpy32(p, m_pData, m_dwSize);
1169 return p;
1170 }
SetRef(CPDF_IndirectObjects * pDoc,FX_DWORD objnum)1171 void CPDF_Reference::SetRef(CPDF_IndirectObjects* pDoc, FX_DWORD objnum)
1172 {
1173 m_pObjList = pDoc;
1174 m_RefObjNum = objnum;
1175 }
CPDF_IndirectObjects(CPDF_Parser * pParser)1176 CPDF_IndirectObjects::CPDF_IndirectObjects(CPDF_Parser* pParser)
1177 {
1178 m_pParser = pParser;
1179 m_IndirectObjs.InitHashTable(1013);
1180 if (pParser) {
1181 m_LastObjNum = m_pParser->GetLastObjNum();
1182 } else {
1183 m_LastObjNum = 0;
1184 }
1185 }
~CPDF_IndirectObjects()1186 CPDF_IndirectObjects::~CPDF_IndirectObjects()
1187 {
1188 FX_POSITION pos = m_IndirectObjs.GetStartPosition();
1189 while (pos) {
1190 FX_LPVOID key, value;
1191 m_IndirectObjs.GetNextAssoc(pos, key, value);
1192 ((CPDF_Object*)value)->Destroy();
1193 }
1194 }
GetIndirectObject(FX_DWORD objnum,struct PARSE_CONTEXT * pContext)1195 CPDF_Object* CPDF_IndirectObjects::GetIndirectObject(FX_DWORD objnum, struct PARSE_CONTEXT* pContext)
1196 {
1197 if (objnum == 0) {
1198 return NULL;
1199 }
1200 FX_LPVOID value;
1201 {
1202 if (m_IndirectObjs.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, value)) {
1203 if (((CPDF_Object*)value)->GetObjNum() == -1) {
1204 return NULL;
1205 }
1206 return (CPDF_Object*)value;
1207 }
1208 }
1209 CPDF_Object* pObj = NULL;
1210 if (m_pParser) {
1211 pObj = m_pParser->ParseIndirectObject(this, objnum, pContext);
1212 }
1213 if (pObj == NULL) {
1214 return NULL;
1215 }
1216 pObj->m_ObjNum = objnum;
1217 if (m_LastObjNum < objnum) {
1218 m_LastObjNum = objnum;
1219 }
1220 if (m_IndirectObjs.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, value)) {
1221 if (value) {
1222 ((CPDF_Object *)value)->Destroy();
1223 }
1224 }
1225 m_IndirectObjs.SetAt((FX_LPVOID)(FX_UINTPTR)objnum, pObj);
1226 return pObj;
1227 }
GetIndirectType(FX_DWORD objnum)1228 int CPDF_IndirectObjects::GetIndirectType(FX_DWORD objnum)
1229 {
1230 FX_LPVOID value;
1231 if (m_IndirectObjs.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, value)) {
1232 return ((CPDF_Object*)value)->GetType();
1233 }
1234 if (m_pParser) {
1235 PARSE_CONTEXT context;
1236 FXSYS_memset32(&context, 0, sizeof(PARSE_CONTEXT));
1237 context.m_Flags = PDFPARSE_TYPEONLY;
1238 return (int)(FX_UINTPTR)m_pParser->ParseIndirectObject(this, objnum, &context);
1239 }
1240 return 0;
1241 }
AddIndirectObject(CPDF_Object * pObj)1242 FX_DWORD CPDF_IndirectObjects::AddIndirectObject(CPDF_Object* pObj)
1243 {
1244 if (pObj->m_ObjNum) {
1245 return pObj->m_ObjNum;
1246 }
1247 m_LastObjNum ++;
1248 m_IndirectObjs.SetAt((FX_LPVOID)(FX_UINTPTR)m_LastObjNum, pObj);
1249 pObj->m_ObjNum = m_LastObjNum;
1250 return m_LastObjNum;
1251 }
ReleaseIndirectObject(FX_DWORD objnum)1252 void CPDF_IndirectObjects::ReleaseIndirectObject(FX_DWORD objnum)
1253 {
1254 FX_LPVOID value;
1255 if (!m_IndirectObjs.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, value)) {
1256 return;
1257 }
1258 if (((CPDF_Object*)value)->GetObjNum() == -1) {
1259 return;
1260 }
1261 ((CPDF_Object*)value)->Destroy();
1262 m_IndirectObjs.RemoveKey((FX_LPVOID)(FX_UINTPTR)objnum);
1263 }
InsertIndirectObject(FX_DWORD objnum,CPDF_Object * pObj)1264 void CPDF_IndirectObjects::InsertIndirectObject(FX_DWORD objnum, CPDF_Object* pObj)
1265 {
1266 if (objnum == 0 || pObj == NULL) {
1267 return;
1268 }
1269 FX_LPVOID value = NULL;
1270 if (m_IndirectObjs.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, value)) {
1271 if (value)
1272 {
1273 if (pObj->GetGenNum() <= ((CPDF_Object*)value)->GetGenNum())
1274 return;
1275 else
1276 ((CPDF_Object*)value)->Destroy();
1277 }
1278 }
1279 pObj->m_ObjNum = objnum;
1280 m_IndirectObjs.SetAt((FX_LPVOID)(FX_UINTPTR)objnum, pObj);
1281 if (m_LastObjNum < objnum) {
1282 m_LastObjNum = objnum;
1283 }
1284 }
GetLastObjNum() const1285 FX_DWORD CPDF_IndirectObjects::GetLastObjNum() const
1286 {
1287 return m_LastObjNum;
1288 }
1289