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