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_serial.h" 8 #include "editint.h" 9 #define PDF_OBJECTSTREAM_MAXLENGTH (256 * 1024) 10 #define PDF_XREFSTREAM_MAXSIZE 10000 11 extern void FlateEncode(const FX_BYTE* src_buf, FX_DWORD src_data, FX_LPBYTE& dest_buf, FX_DWORD& dest_size); 12 extern void FlateEncode(FX_LPCBYTE src_buf, FX_DWORD src_size, int predictor, int Colors, int BitsPerComponent, int Columns, 13 FX_LPBYTE& dest_buf, FX_DWORD& dest_size); 14 extern FX_BOOL IsSignatureDict(const CPDF_Dictionary* pDict); 15 FX_INT32 PDF_CreatorAppendObject(const CPDF_Object* pObj, CFX_FileBufferArchive *pFile, FX_FILESIZE& offset) 16 { 17 FX_INT32 len = 0; 18 if (pObj == NULL) { 19 if (pFile->AppendString(FX_BSTRC(" null")) < 0) { 20 return -1; 21 } 22 offset += 5; 23 return 1; 24 } 25 switch (pObj->GetType()) { 26 case PDFOBJ_NULL: 27 if (pFile->AppendString(FX_BSTRC(" null")) < 0) { 28 return -1; 29 } 30 offset += 5; 31 break; 32 case PDFOBJ_BOOLEAN: 33 case PDFOBJ_NUMBER: 34 if (pFile->AppendString(FX_BSTRC(" ")) < 0) { 35 return -1; 36 } 37 if ((len = pFile->AppendString(pObj->GetString())) < 0) { 38 return -1; 39 } 40 offset += len + 1; 41 break; 42 case PDFOBJ_STRING: { 43 CFX_ByteString str = pObj->GetString(); 44 FX_BOOL bHex = ((CPDF_String*)pObj)->IsHex(); 45 if ((len = pFile->AppendString(PDF_EncodeString(str, bHex))) < 0) { 46 return -1; 47 } 48 offset += len; 49 break; 50 } 51 case PDFOBJ_NAME: { 52 if (pFile->AppendString(FX_BSTRC("/")) < 0) { 53 return -1; 54 } 55 CFX_ByteString str = pObj->GetString(); 56 if ((len = pFile->AppendString(PDF_NameEncode(str))) < 0) { 57 return -1; 58 } 59 offset += len + 1; 60 break; 61 } 62 case PDFOBJ_REFERENCE: { 63 if (pFile->AppendString(FX_BSTRC(" ")) < 0) { 64 return -1; 65 } 66 CPDF_Reference* p = (CPDF_Reference*)pObj; 67 if ((len = pFile->AppendDWord(p->GetRefObjNum())) < 0) { 68 return -1; 69 } 70 if (pFile->AppendString(FX_BSTRC(" 0 R ")) < 0) { 71 return -1; 72 } 73 offset += len + 6; 74 break; 75 } 76 case PDFOBJ_ARRAY: { 77 if (pFile->AppendString(FX_BSTRC("[")) < 0) { 78 return -1; 79 } 80 offset += 1; 81 CPDF_Array* p = (CPDF_Array*)pObj; 82 for (FX_DWORD i = 0; i < p->GetCount(); i ++) { 83 CPDF_Object* pElement = p->GetElement(i); 84 if (pElement->GetObjNum()) { 85 if (pFile->AppendString(FX_BSTRC(" ")) < 0) { 86 return -1; 87 } 88 if ((len = pFile->AppendDWord(pElement->GetObjNum())) < 0) { 89 return -1; 90 } 91 if (pFile->AppendString(FX_BSTRC(" 0 R")) < 0) { 92 return -1; 93 } 94 offset += len + 5; 95 } else { 96 if (PDF_CreatorAppendObject(pElement, pFile, offset) < 0) { 97 return -1; 98 } 99 } 100 } 101 if (pFile->AppendString(FX_BSTRC("]")) < 0) { 102 return -1; 103 } 104 offset += 1; 105 break; 106 } 107 case PDFOBJ_DICTIONARY: { 108 if (pFile->AppendString(FX_BSTRC("<<")) < 0) { 109 return -1; 110 } 111 offset += 2; 112 CPDF_Dictionary* p = (CPDF_Dictionary*)pObj; 113 FX_POSITION pos = p->GetStartPos(); 114 while (pos) { 115 CFX_ByteString key; 116 CPDF_Object* pValue = p->GetNextElement(pos, key); 117 if (pFile->AppendString(FX_BSTRC("/")) < 0) { 118 return -1; 119 } 120 if ((len = pFile->AppendString(PDF_NameEncode(key))) < 0) { 121 return -1; 122 } 123 offset += len + 1; 124 if (pValue->GetObjNum()) { 125 if (pFile->AppendString(FX_BSTRC(" ")) < 0) { 126 return -1; 127 } 128 if ((len = pFile->AppendDWord(pValue->GetObjNum())) < 0) { 129 return -1; 130 } 131 if (pFile->AppendString(FX_BSTRC(" 0 R")) < 0) { 132 return -1; 133 } 134 offset += len + 5; 135 } else { 136 if (PDF_CreatorAppendObject(pValue, pFile, offset) < 0) { 137 return -1; 138 } 139 } 140 } 141 if (pFile->AppendString(FX_BSTRC(">>")) < 0) { 142 return -1; 143 } 144 offset += 2; 145 break; 146 } 147 case PDFOBJ_STREAM: { 148 CPDF_Stream* p = (CPDF_Stream*)pObj; 149 if (PDF_CreatorAppendObject(p->GetDict(), pFile, offset) < 0) { 150 return -1; 151 } 152 if (pFile->AppendString(FX_BSTRC("stream\r\n")) < 0) { 153 return -1; 154 } 155 offset += 8; 156 CPDF_StreamAcc acc; 157 acc.LoadAllData(p, TRUE); 158 if (pFile->AppendBlock(acc.GetData(), acc.GetSize()) < 0) { 159 return -1; 160 } 161 offset += acc.GetSize(); 162 if ((len = pFile->AppendString(FX_BSTRC("\r\nendstream"))) < 0) { 163 return -1; 164 } 165 offset += len; 166 break; 167 } 168 default: 169 ASSERT(FALSE); 170 break; 171 } 172 return 1; 173 } 174 FX_INT32 PDF_CreatorWriteTrailer(CPDF_Document* pDocument, CFX_FileBufferArchive* pFile, CPDF_Array* pIDArray, FX_BOOL bCompress) 175 { 176 FX_FILESIZE offset = 0; 177 FX_INT32 len = 0; 178 FXSYS_assert(pDocument && pFile); 179 CPDF_Parser *pParser = (CPDF_Parser*)pDocument->GetParser(); 180 if (pParser) { 181 CPDF_Dictionary* p = pParser->GetTrailer(); 182 FX_POSITION pos = p->GetStartPos(); 183 while (pos) { 184 CFX_ByteString key; 185 CPDF_Object* pValue = p->GetNextElement(pos, key); 186 if (key == FX_BSTRC("Encrypt") || key == FX_BSTRC("Size") || key == FX_BSTRC("Filter") || 187 key == FX_BSTRC("Index") || key == FX_BSTRC("Length") || key == FX_BSTRC("Prev") || 188 key == FX_BSTRC("W") || key == FX_BSTRC("XRefStm") || key == FX_BSTRC("Type") || key == FX_BSTRC("ID")) { 189 continue; 190 } 191 if (bCompress && key == FX_BSTRC("DecodeParms")) { 192 continue; 193 } 194 if (pFile->AppendString((FX_BSTRC("/"))) < 0) { 195 return -1; 196 } 197 if ((len = pFile->AppendString(PDF_NameEncode(key))) < 0) { 198 return -1; 199 } 200 offset += len + 1; 201 if (pValue->GetObjNum()) { 202 if (pFile->AppendString(FX_BSTRC(" ")) < 0) { 203 return -1; 204 } 205 if ((len = pFile->AppendDWord(pValue->GetObjNum())) < 0) { 206 return -1; 207 } 208 if (pFile->AppendString(FX_BSTRC(" 0 R ")) < 0) { 209 return -1; 210 } 211 offset += len + 6; 212 } else { 213 if (PDF_CreatorAppendObject(pValue, pFile, offset) < 0) { 214 return -1; 215 } 216 } 217 } 218 if (pIDArray) { 219 if (pFile->AppendString((FX_BSTRC("/ID"))) < 0) { 220 return -1; 221 } 222 offset += 3; 223 if (PDF_CreatorAppendObject(pIDArray, pFile, offset) < 0) { 224 return -1; 225 } 226 } 227 return offset; 228 } 229 if (pFile->AppendString(FX_BSTRC("\r\n/Root ")) < 0) { 230 return -1; 231 } 232 if ((len = pFile->AppendDWord(pDocument->GetRoot()->GetObjNum())) < 0) { 233 return -1; 234 } 235 if (pFile->AppendString(FX_BSTRC(" 0 R\r\n")) < 0) { 236 return -1; 237 } 238 offset += len + 14; 239 if (pDocument->GetInfo()) { 240 if (pFile->AppendString(FX_BSTRC("/Info ")) < 0) { 241 return -1; 242 } 243 if ((len = pFile->AppendDWord(pDocument->GetInfo()->GetObjNum())) < 0) { 244 return -1; 245 } 246 if (pFile->AppendString(FX_BSTRC(" 0 R\r\n")) < 0) { 247 return -1; 248 } 249 offset += len + 12; 250 } 251 if (pIDArray) { 252 if (pFile->AppendString((FX_BSTRC("/ID"))) < 0) { 253 return -1; 254 } 255 offset += 3; 256 if (PDF_CreatorAppendObject(pIDArray, pFile, offset) < 0) { 257 return -1; 258 } 259 } 260 return offset; 261 } 262 FX_INT32 PDF_CreatorWriteEncrypt(const CPDF_Dictionary* pEncryptDict, FX_DWORD dwObjNum, CFX_FileBufferArchive *pFile) 263 { 264 if (!pEncryptDict) { 265 return 0; 266 } 267 FXSYS_assert(pFile); 268 FX_FILESIZE offset = 0; 269 FX_INT32 len = 0; 270 if (pFile->AppendString(FX_BSTRC("/Encrypt")) < 0) { 271 return -1; 272 } 273 offset += 8; 274 if (pFile->AppendString(FX_BSTRC(" ")) < 0) { 275 return -1; 276 } 277 if ((len = pFile->AppendDWord(dwObjNum)) < 0) { 278 return -1; 279 } 280 if (pFile->AppendString(FX_BSTRC(" 0 R ")) < 0) { 281 return -1; 282 } 283 offset += len + 6; 284 return offset; 285 } 286 FX_BOOL PDF_GenerateFileID(FX_DWORD dwSeed1, FX_DWORD dwSeed2, FX_LPDWORD pBuffer) 287 { 288 if (!pBuffer) { 289 return FALSE; 290 } 291 FX_LPVOID pContext = FX_Random_MT_Start(dwSeed1); 292 FX_INT32 i = 0; 293 for (i = 0; i < 2; i++) { 294 *pBuffer++ = FX_Random_MT_Generate(pContext); 295 } 296 FX_Random_MT_Close(pContext); 297 pContext = FX_Random_MT_Start(dwSeed2); 298 for (i = 0; i < 2; i++) { 299 *pBuffer++ = FX_Random_MT_Generate(pContext); 300 } 301 FX_Random_MT_Close(pContext); 302 return TRUE; 303 } 304 class CPDF_FlateEncoder 305 { 306 public: 307 CPDF_FlateEncoder(); 308 ~CPDF_FlateEncoder(); 309 FX_BOOL Initialize(CPDF_Stream* pStream, FX_BOOL bFlateEncode); 310 FX_BOOL Initialize(FX_LPCBYTE pBuffer, FX_DWORD size, FX_BOOL bFlateEncode, FX_BOOL bXRefStream = FALSE); 311 void CloneDict(); 312 FX_LPBYTE m_pData; 313 FX_DWORD m_dwSize; 314 CPDF_Dictionary* m_pDict; 315 FX_BOOL m_bCloned; 316 FX_BOOL m_bNewData; 317 CPDF_StreamAcc m_Acc; 318 }; 319 CPDF_FlateEncoder::CPDF_FlateEncoder() 320 { 321 m_pData = NULL; 322 m_dwSize = 0; 323 m_pDict = NULL; 324 m_bCloned = FALSE; 325 m_bNewData = FALSE; 326 } 327 void CPDF_FlateEncoder::CloneDict() 328 { 329 if (!m_bCloned) { 330 m_pDict = (CPDF_Dictionary*)m_pDict->Clone(); 331 m_bCloned = TRUE; 332 } 333 } 334 FX_BOOL CPDF_FlateEncoder::Initialize(CPDF_Stream* pStream, FX_BOOL bFlateEncode) 335 { 336 m_Acc.LoadAllData(pStream, TRUE); 337 if (pStream->GetDict()->KeyExist("Filter") || !bFlateEncode) { 338 if (pStream->GetDict()->KeyExist("Filter") && !bFlateEncode) { 339 CPDF_StreamAcc destAcc; 340 destAcc.LoadAllData(pStream); 341 m_dwSize = destAcc.GetSize(); 342 m_pData = (FX_LPBYTE)destAcc.DetachData(); 343 m_pDict = (CPDF_Dictionary*)pStream->GetDict()->Clone(); 344 m_pDict->RemoveAt(FX_BSTRC("Filter")); 345 m_bNewData = TRUE; 346 m_bCloned = TRUE; 347 } else { 348 m_pData = (FX_LPBYTE)m_Acc.GetData(); 349 m_dwSize = m_Acc.GetSize(); 350 m_pDict = pStream->GetDict(); 351 } 352 return TRUE; 353 } 354 m_pData = NULL; 355 m_dwSize = 0; 356 m_bNewData = TRUE; 357 m_bCloned = TRUE; 358 ::FlateEncode(m_Acc.GetData(), m_Acc.GetSize(), m_pData, m_dwSize); 359 m_pDict = (CPDF_Dictionary*)pStream->GetDict()->Clone(); 360 m_pDict->SetAtInteger("Length", m_dwSize); 361 m_pDict->SetAtName("Filter", "FlateDecode"); 362 m_pDict->RemoveAt("DecodeParms"); 363 return TRUE; 364 } 365 FX_BOOL CPDF_FlateEncoder::Initialize(FX_LPCBYTE pBuffer, FX_DWORD size, FX_BOOL bFlateEncode, FX_BOOL bXRefStream) 366 { 367 if (!bFlateEncode) { 368 m_pData = (FX_LPBYTE)pBuffer; 369 m_dwSize = size; 370 return TRUE; 371 } 372 m_bNewData = TRUE; 373 if (bXRefStream) { 374 ::FlateEncode(pBuffer, size, 12, 1, 8, 7, m_pData, m_dwSize); 375 } else { 376 ::FlateEncode(pBuffer, size, m_pData, m_dwSize); 377 } 378 return TRUE; 379 } 380 CPDF_FlateEncoder::~CPDF_FlateEncoder() 381 { 382 if (m_bCloned && m_pDict) { 383 m_pDict->Release(); 384 } 385 if (m_bNewData && m_pData) { 386 FX_Free(m_pData); 387 } 388 } 389 class CPDF_Encryptor 390 { 391 public: 392 CPDF_Encryptor(); 393 ~CPDF_Encryptor(); 394 FX_BOOL Initialize(CPDF_CryptoHandler* pHandler, int objnum, FX_LPBYTE src_data, FX_DWORD src_size); 395 FX_LPBYTE m_pData; 396 FX_DWORD m_dwSize; 397 FX_BOOL m_bNewBuf; 398 }; 399 CPDF_Encryptor::CPDF_Encryptor() 400 { 401 m_pData = NULL; 402 m_dwSize = 0; 403 m_bNewBuf = FALSE; 404 } 405 FX_BOOL CPDF_Encryptor::Initialize(CPDF_CryptoHandler* pHandler, int objnum, FX_LPBYTE src_data, FX_DWORD src_size) 406 { 407 if (src_size == 0) { 408 return TRUE; 409 } 410 if (pHandler == NULL) { 411 m_pData = (FX_LPBYTE)src_data; 412 m_dwSize = src_size; 413 m_bNewBuf = FALSE; 414 return TRUE; 415 } 416 m_dwSize = pHandler->EncryptGetSize(objnum, 0, src_data, src_size); 417 m_pData = FX_Alloc(FX_BYTE, m_dwSize); 418 if(!m_pData) { 419 return FALSE; 420 } 421 pHandler->EncryptContent(objnum, 0, src_data, src_size, m_pData, m_dwSize); 422 m_bNewBuf = TRUE; 423 return TRUE; 424 } 425 CPDF_Encryptor::~CPDF_Encryptor() 426 { 427 if (m_bNewBuf) { 428 FX_Free(m_pData); 429 } 430 } 431 CPDF_ObjectStream::CPDF_ObjectStream() 432 : m_dwObjNum(0) 433 , m_index(0) 434 { 435 } 436 FX_BOOL CPDF_ObjectStream::Start() 437 { 438 m_ObjNumArray.RemoveAll(); 439 m_OffsetArray.RemoveAll(); 440 m_Buffer.Clear(); 441 m_dwObjNum = 0; 442 m_index = 0; 443 return TRUE; 444 } 445 FX_INT32 CPDF_ObjectStream::CompressIndirectObject(FX_DWORD dwObjNum, const CPDF_Object *pObj) 446 { 447 m_ObjNumArray.Add(dwObjNum); 448 m_OffsetArray.Add(m_Buffer.GetLength()); 449 m_Buffer << pObj; 450 return 1; 451 } 452 FX_INT32 CPDF_ObjectStream::CompressIndirectObject(FX_DWORD dwObjNum, FX_LPCBYTE pBuffer, FX_DWORD dwSize) 453 { 454 m_ObjNumArray.Add(dwObjNum); 455 m_OffsetArray.Add(m_Buffer.GetLength()); 456 m_Buffer.AppendBlock(pBuffer, dwSize); 457 return 1; 458 } 459 FX_FILESIZE CPDF_ObjectStream::End(CPDF_Creator* pCreator) 460 { 461 FXSYS_assert(pCreator); 462 if (m_ObjNumArray.GetSize() == 0) { 463 return 0; 464 } 465 CFX_FileBufferArchive *pFile = &pCreator->m_File; 466 CPDF_CryptoHandler *pHandler = pCreator->m_pCryptoHandler; 467 FX_FILESIZE ObjOffset = pCreator->m_Offset; 468 if (!m_dwObjNum) { 469 m_dwObjNum = ++pCreator->m_dwLastObjNum; 470 } 471 CFX_ByteTextBuf tempBuffer; 472 FX_INT32 iCount = m_ObjNumArray.GetSize(); 473 for (FX_INT32 i = 0; i < iCount; i++) { 474 tempBuffer << m_ObjNumArray.ElementAt(i) << FX_BSTRC(" ") << m_OffsetArray.ElementAt(i) << FX_BSTRC(" "); 475 } 476 FX_FILESIZE &offset = pCreator->m_Offset; 477 FX_INT32 len = pFile->AppendDWord(m_dwObjNum); 478 if (len < 0) { 479 return -1; 480 } 481 offset += len; 482 if ((len = pFile->AppendString(FX_BSTRC(" 0 obj\r\n<</Type /ObjStm /N "))) < 0) { 483 return -1; 484 } 485 offset += len; 486 if ((len = pFile->AppendDWord((FX_DWORD)iCount)) < 0) { 487 return -1; 488 } 489 offset += len; 490 if (pFile->AppendString(FX_BSTRC("/First ")) < 0) { 491 return -1; 492 } 493 if ((len = pFile->AppendDWord((FX_DWORD)tempBuffer.GetLength())) < 0) { 494 return -1; 495 } 496 if (pFile->AppendString(FX_BSTRC("/Length ")) < 0) { 497 return -1; 498 } 499 offset += len + 15; 500 if (!pCreator->m_bCompress && !pHandler) { 501 if ((len = pFile->AppendDWord((FX_DWORD)(tempBuffer.GetLength() + m_Buffer.GetLength()))) < 0) { 502 return -1; 503 } 504 offset += len; 505 if ((len = pFile->AppendString(FX_BSTRC(">>stream\r\n"))) < 0) { 506 return -1; 507 } 508 if (pFile->AppendBlock(tempBuffer.GetBuffer(), tempBuffer.GetLength()) < 0) { 509 return -1; 510 } 511 if (pFile->AppendBlock(m_Buffer.GetBuffer(), m_Buffer.GetLength()) < 0) { 512 return -1; 513 } 514 offset += len + tempBuffer.GetLength() + m_Buffer.GetLength(); 515 } else { 516 tempBuffer << m_Buffer; 517 CPDF_FlateEncoder encoder; 518 encoder.Initialize(tempBuffer.GetBuffer(), tempBuffer.GetLength(), pCreator->m_bCompress); 519 CPDF_Encryptor encryptor; 520 encryptor.Initialize(pHandler, m_dwObjNum, encoder.m_pData, encoder.m_dwSize); 521 if ((len = pFile->AppendDWord(encryptor.m_dwSize)) < 0) { 522 return -1; 523 } 524 offset += len; 525 if (pCreator->m_bCompress) { 526 if (pFile->AppendString(FX_BSTRC("/Filter /FlateDecode")) < 0) { 527 return -1; 528 } 529 offset += 20; 530 } 531 if ((len = pFile->AppendString(FX_BSTRC(">>stream\r\n"))) < 0) { 532 return -1; 533 } 534 if (pFile->AppendBlock(encryptor.m_pData, encryptor.m_dwSize) < 0) { 535 return -1; 536 } 537 offset += len + encryptor.m_dwSize; 538 } 539 if ((len = pFile->AppendString(FX_BSTRC("\r\nendstream\r\nendobj\r\n"))) < 0) { 540 return -1; 541 } 542 offset += len; 543 return ObjOffset; 544 } 545 CPDF_XRefStream::CPDF_XRefStream() 546 : m_PrevOffset(0) 547 , m_iSeg(0) 548 , m_dwTempObjNum(0) 549 { 550 } 551 FX_BOOL CPDF_XRefStream::Start() 552 { 553 m_IndexArray.RemoveAll(); 554 m_Buffer.Clear(); 555 m_iSeg = 0; 556 return TRUE; 557 } 558 FX_INT32 CPDF_XRefStream::CompressIndirectObject(FX_DWORD dwObjNum, const CPDF_Object *pObj, CPDF_Creator *pCreator) 559 { 560 if (!pCreator) { 561 return 0; 562 } 563 m_ObjStream.CompressIndirectObject(dwObjNum, pObj); 564 if (m_ObjStream.m_ObjNumArray.GetSize() < pCreator->m_ObjectStreamSize && 565 m_ObjStream.m_Buffer.GetLength() < PDF_OBJECTSTREAM_MAXLENGTH) { 566 return 1; 567 } 568 return EndObjectStream(pCreator); 569 } 570 FX_INT32 CPDF_XRefStream::CompressIndirectObject(FX_DWORD dwObjNum, FX_LPCBYTE pBuffer, FX_DWORD dwSize, CPDF_Creator *pCreator) 571 { 572 if (!pCreator) { 573 return 0; 574 } 575 m_ObjStream.CompressIndirectObject(dwObjNum, pBuffer, dwSize); 576 if (m_ObjStream.m_ObjNumArray.GetSize() < pCreator->m_ObjectStreamSize && 577 m_ObjStream.m_Buffer.GetLength() < PDF_OBJECTSTREAM_MAXLENGTH) { 578 return 1; 579 } 580 return EndObjectStream(pCreator); 581 } 582 static void _AppendIndex0(CFX_ByteTextBuf& buffer, FX_BOOL bFirstObject = TRUE) 583 { 584 buffer.AppendByte(0); 585 buffer.AppendByte(0); 586 buffer.AppendByte(0); 587 buffer.AppendByte(0); 588 buffer.AppendByte(0); 589 if (bFirstObject) { 590 buffer.AppendByte(0xFF); 591 buffer.AppendByte(0xFF); 592 } else { 593 buffer.AppendByte(0); 594 buffer.AppendByte(0); 595 } 596 } 597 static void _AppendIndex1(CFX_ByteTextBuf& buffer, FX_FILESIZE offset) 598 { 599 buffer.AppendByte(1); 600 buffer.AppendByte(FX_GETBYTEOFFSET24(offset)); 601 buffer.AppendByte(FX_GETBYTEOFFSET16(offset)); 602 buffer.AppendByte(FX_GETBYTEOFFSET8(offset)); 603 buffer.AppendByte(FX_GETBYTEOFFSET0(offset)); 604 buffer.AppendByte(0); 605 buffer.AppendByte(0); 606 } 607 static void _AppendIndex2(CFX_ByteTextBuf& buffer, FX_DWORD objnum, FX_INT32 index) 608 { 609 buffer.AppendByte(2); 610 buffer.AppendByte(FX_GETBYTEOFFSET24(objnum)); 611 buffer.AppendByte(FX_GETBYTEOFFSET16(objnum)); 612 buffer.AppendByte(FX_GETBYTEOFFSET8(objnum)); 613 buffer.AppendByte(FX_GETBYTEOFFSET0(objnum)); 614 buffer.AppendByte(FX_GETBYTEOFFSET8(index)); 615 buffer.AppendByte(FX_GETBYTEOFFSET0(index)); 616 } 617 FX_INT32 CPDF_XRefStream::EndObjectStream(CPDF_Creator *pCreator, FX_BOOL bEOF) 618 { 619 FX_FILESIZE objOffset = 0; 620 if (bEOF) { 621 objOffset = m_ObjStream.End(pCreator); 622 if (objOffset < 0) { 623 return -1; 624 } 625 } 626 FX_DWORD &dwObjStmNum = m_ObjStream.m_dwObjNum; 627 if (!dwObjStmNum) { 628 dwObjStmNum = ++pCreator->m_dwLastObjNum; 629 } 630 FX_INT32 iSize = m_ObjStream.m_ObjNumArray.GetSize(); 631 FX_INT32 iSeg = m_IndexArray.GetSize() / 2; 632 if (!(pCreator->m_dwFlags & FPDFCREATE_INCREMENTAL)) { 633 if (m_dwTempObjNum == 0) { 634 _AppendIndex0(m_Buffer); 635 m_dwTempObjNum++; 636 } 637 FX_DWORD end_num = m_IndexArray.GetAt((iSeg - 1) * 2) + m_IndexArray.GetAt((iSeg - 1) * 2 + 1); 638 int index = 0; 639 for (; m_dwTempObjNum < end_num; m_dwTempObjNum++) { 640 FX_FILESIZE* offset = pCreator->m_ObjectOffset.GetPtrAt(m_dwTempObjNum); 641 if (offset) { 642 if (index >= iSize || m_dwTempObjNum != m_ObjStream.m_ObjNumArray[index]) { 643 _AppendIndex1(m_Buffer, *offset); 644 } else { 645 _AppendIndex2(m_Buffer, dwObjStmNum, index++); 646 } 647 } else { 648 _AppendIndex0(m_Buffer, FALSE); 649 } 650 } 651 if (iSize > 0 && bEOF) { 652 pCreator->m_ObjectOffset.Add(dwObjStmNum, 1); 653 pCreator->m_ObjectSize.Add(dwObjStmNum, 1); 654 pCreator->m_ObjectOffset[dwObjStmNum] = objOffset; 655 } 656 m_iSeg = iSeg; 657 if (bEOF) { 658 m_ObjStream.Start(); 659 } 660 return 1; 661 } 662 FX_INT32 &j = m_ObjStream.m_index; 663 for (int i = m_iSeg; i < iSeg; i++) { 664 FX_DWORD start = m_IndexArray.ElementAt(i * 2); 665 FX_DWORD end = m_IndexArray.ElementAt(i * 2 + 1) + start; 666 for (FX_DWORD m = start; m < end; m++) { 667 if (j >= iSize || m != m_ObjStream.m_ObjNumArray.ElementAt(j)) { 668 _AppendIndex1(m_Buffer, pCreator->m_ObjectOffset[m]); 669 } else { 670 _AppendIndex2(m_Buffer, dwObjStmNum, j++); 671 } 672 } 673 } 674 if (iSize > 0 && bEOF) { 675 _AppendIndex1(m_Buffer, objOffset); 676 m_IndexArray.Add(dwObjStmNum); 677 m_IndexArray.Add(1); 678 iSeg += 1; 679 } 680 m_iSeg = iSeg; 681 if (bEOF) { 682 m_ObjStream.Start(); 683 } 684 return 1; 685 } 686 FX_BOOL CPDF_XRefStream::GenerateXRefStream(CPDF_Creator* pCreator, FX_BOOL bEOF) 687 { 688 FX_FILESIZE offset_tmp = pCreator->m_Offset; 689 FX_DWORD objnum = ++pCreator->m_dwLastObjNum; 690 CFX_FileBufferArchive *pFile = &pCreator->m_File; 691 FX_BOOL bIncremental = (pCreator->m_dwFlags & FPDFCREATE_INCREMENTAL) != 0; 692 if (bIncremental) { 693 AddObjectNumberToIndexArray(objnum); 694 } else { 695 for (; m_dwTempObjNum < pCreator->m_dwLastObjNum; m_dwTempObjNum++) { 696 FX_FILESIZE* offset = pCreator->m_ObjectOffset.GetPtrAt(m_dwTempObjNum); 697 if (offset) { 698 _AppendIndex1(m_Buffer, *offset); 699 } else { 700 _AppendIndex0(m_Buffer, FALSE); 701 } 702 } 703 } 704 _AppendIndex1(m_Buffer, offset_tmp); 705 FX_FILESIZE &offset = pCreator->m_Offset; 706 FX_INT32 len = pFile->AppendDWord(objnum); 707 if (len < 0) { 708 return FALSE; 709 } 710 offset += len; 711 if ((len = pFile->AppendString(FX_BSTRC(" 0 obj\r\n<</Type /XRef/W[1 4 2]/Index["))) < 0) { 712 return FALSE; 713 } 714 offset += len; 715 if (!bIncremental) { 716 if ((len = pFile->AppendDWord(0)) < 0) { 717 return FALSE; 718 } 719 if ((len = pFile->AppendString(FX_BSTRC(" "))) < 0) { 720 return FALSE; 721 } 722 offset += len + 1; 723 if ((len = pFile->AppendDWord(objnum + 1)) < 0) { 724 return FALSE; 725 } 726 offset += len; 727 } else { 728 FX_INT32 iSeg = m_IndexArray.GetSize() / 2; 729 for (FX_INT32 i = 0; i < iSeg; i++) { 730 if ((len = pFile->AppendDWord(m_IndexArray.ElementAt(i * 2))) < 0) { 731 return FALSE; 732 } 733 if (pFile->AppendString(FX_BSTRC(" ")) < 0) { 734 return FALSE; 735 } 736 offset += len + 1; 737 if ((len = pFile->AppendDWord(m_IndexArray.ElementAt(i * 2 + 1))) < 0) { 738 return FALSE; 739 } 740 if (pFile->AppendString(FX_BSTRC(" ")) < 0) { 741 return FALSE; 742 } 743 offset += len + 1; 744 } 745 } 746 if (pFile->AppendString(FX_BSTRC("]/Size ")) < 0) { 747 return FALSE; 748 } 749 if ((len = pFile->AppendDWord(objnum + 1)) < 0) { 750 return FALSE; 751 } 752 offset += len + 7; 753 if (m_PrevOffset > 0) { 754 if (pFile->AppendString(FX_BSTRC("/Prev ")) < 0) { 755 return -1; 756 } 757 FX_CHAR offset_buf[20]; 758 FXSYS_memset32(offset_buf, 0, sizeof(offset_buf)); 759 FXSYS_i64toa(m_PrevOffset, offset_buf, 10); 760 FX_INT32 len = (FX_INT32)FXSYS_strlen(offset_buf); 761 if (pFile->AppendBlock(offset_buf, len) < 0) { 762 return -1; 763 } 764 offset += len + 6; 765 } 766 FX_BOOL bPredictor = TRUE; 767 CPDF_FlateEncoder encoder; 768 encoder.Initialize(m_Buffer.GetBuffer(), m_Buffer.GetLength(), pCreator->m_bCompress, bPredictor); 769 if (pCreator->m_bCompress) { 770 if (pFile->AppendString(FX_BSTRC("/Filter /FlateDecode")) < 0) { 771 return FALSE; 772 } 773 offset += 20; 774 if (bPredictor) { 775 if ((len = pFile->AppendString(FX_BSTRC("/DecodeParms<</Columns 7/Predictor 12>>"))) < 0) { 776 return FALSE; 777 } 778 offset += len; 779 } 780 } 781 if (pFile->AppendString(FX_BSTRC("/Length ")) < 0) { 782 return FALSE; 783 } 784 if ((len = pFile->AppendDWord(encoder.m_dwSize)) < 0) { 785 return FALSE; 786 } 787 offset += len + 8; 788 if (bEOF) { 789 if ((len = PDF_CreatorWriteTrailer(pCreator->m_pDocument, pFile, pCreator->m_pIDArray, pCreator->m_bCompress)) < 0) { 790 return -1; 791 } 792 offset += len; 793 if (pCreator->m_pEncryptDict) { 794 FX_DWORD dwEncryptObjNum = pCreator->m_pEncryptDict->GetObjNum(); 795 if (dwEncryptObjNum == 0) { 796 dwEncryptObjNum = pCreator->m_dwEnryptObjNum; 797 } 798 if ((len = PDF_CreatorWriteEncrypt(pCreator->m_pEncryptDict, dwEncryptObjNum, pFile)) < 0) { 799 return -1; 800 } 801 offset += len; 802 } 803 } 804 if ((len = pFile->AppendString(FX_BSTRC(">>stream\r\n"))) < 0) { 805 return FALSE; 806 } 807 offset += len; 808 if (pFile->AppendBlock(encoder.m_pData, encoder.m_dwSize) < 0) { 809 return FALSE; 810 } 811 if ((len = pFile->AppendString(FX_BSTRC("\r\nendstream\r\nendobj\r\n"))) < 0) { 812 return FALSE; 813 } 814 offset += encoder.m_dwSize + len; 815 m_PrevOffset = offset_tmp; 816 return TRUE; 817 } 818 FX_BOOL CPDF_XRefStream::End(CPDF_Creator *pCreator, FX_BOOL bEOF ) 819 { 820 if (EndObjectStream(pCreator, bEOF) < 0) { 821 return FALSE; 822 } 823 return GenerateXRefStream(pCreator, bEOF); 824 } 825 FX_BOOL CPDF_XRefStream::EndXRefStream(CPDF_Creator* pCreator) 826 { 827 if (!(pCreator->m_dwFlags & FPDFCREATE_INCREMENTAL)) { 828 _AppendIndex0(m_Buffer); 829 for (FX_DWORD i = 1; i < pCreator->m_dwLastObjNum + 1; i++) { 830 FX_FILESIZE* offset = pCreator->m_ObjectOffset.GetPtrAt(i); 831 if (offset) { 832 _AppendIndex1(m_Buffer, *offset); 833 } else { 834 _AppendIndex0(m_Buffer, FALSE); 835 } 836 } 837 } else { 838 FX_INT32 iSeg = m_IndexArray.GetSize() / 2; 839 for (int i = 0; i < iSeg; i++) { 840 FX_DWORD start = m_IndexArray.ElementAt(i * 2); 841 FX_DWORD end = m_IndexArray.ElementAt(i * 2 + 1) + start; 842 for (FX_DWORD j = start; j < end; j++) { 843 _AppendIndex1(m_Buffer, pCreator->m_ObjectOffset[j]); 844 } 845 } 846 } 847 return GenerateXRefStream(pCreator, FALSE); 848 } 849 FX_BOOL CPDF_XRefStream::AddObjectNumberToIndexArray(FX_DWORD objnum) 850 { 851 FX_INT32 iSize = m_IndexArray.GetSize(); 852 if (iSize == 0) { 853 m_IndexArray.Add(objnum); 854 m_IndexArray.Add(1); 855 } else { 856 FXSYS_assert(iSize > 1); 857 FX_DWORD startobjnum = m_IndexArray.ElementAt(iSize - 2); 858 FX_INT32 iCount = m_IndexArray.ElementAt(iSize - 1); 859 if (objnum == startobjnum + iCount) { 860 m_IndexArray[iSize - 1] = iCount + 1; 861 } else { 862 m_IndexArray.Add(objnum); 863 m_IndexArray.Add(1); 864 } 865 } 866 return TRUE; 867 } 868 CPDF_Creator::CPDF_Creator(CPDF_Document* pDoc) 869 { 870 m_pDocument = pDoc; 871 m_pParser = (CPDF_Parser*)pDoc->m_pParser; 872 m_bCompress = TRUE; 873 if (m_pParser) { 874 m_pEncryptDict = m_pParser->GetEncryptDict(); 875 m_pCryptoHandler = m_pParser->GetCryptoHandler(); 876 } else { 877 m_pEncryptDict = NULL; 878 m_pCryptoHandler = NULL; 879 } 880 m_bSecurityChanged = FALSE; 881 m_bStandardSecurity = FALSE; 882 m_pMetadata = NULL; 883 m_bEncryptCloned = FALSE; 884 m_bEncryptMetadata = FALSE; 885 m_Offset = 0; 886 m_iStage = -1; 887 m_dwFlags = 0; 888 m_Pos = NULL; 889 m_XrefStart = 0; 890 m_pXRefStream = NULL; 891 m_ObjectStreamSize = 200; 892 m_dwLastObjNum = m_pDocument->GetLastObjNum(); 893 m_pIDArray = NULL; 894 m_FileVersion = 0; 895 m_dwEnryptObjNum = 0; 896 m_bNewCrypto = FALSE; 897 } 898 CPDF_Creator::~CPDF_Creator() 899 { 900 ResetStandardSecurity(); 901 if (m_bEncryptCloned && m_pEncryptDict) { 902 m_pEncryptDict->Release(); 903 m_pEncryptDict = NULL; 904 } 905 Clear(); 906 } 907 static FX_BOOL _IsXRefNeedEnd(CPDF_XRefStream* pXRef, FX_DWORD flag) 908 { 909 if (!(flag & FPDFCREATE_INCREMENTAL)) { 910 return FALSE; 911 } 912 FX_INT32 iSize = pXRef->m_IndexArray.GetSize() / 2; 913 FX_INT32 iCount = 0; 914 for (FX_INT32 i = 0; i < iSize; i++) { 915 iCount += pXRef->m_IndexArray.ElementAt(i * 2 + 1); 916 } 917 return (iCount >= PDF_XREFSTREAM_MAXSIZE); 918 } 919 FX_INT32 CPDF_Creator::WriteIndirectObjectToStream(const CPDF_Object* pObj) 920 { 921 if (!m_pXRefStream) { 922 return 1; 923 } 924 FX_DWORD objnum = pObj->GetObjNum(); 925 if (m_pParser && m_pParser->m_ObjVersion.GetSize() > (FX_INT32)objnum && m_pParser->m_ObjVersion[objnum] > 0) { 926 return 1; 927 } 928 if (pObj->GetType() == PDFOBJ_NUMBER) { 929 return 1; 930 } 931 CPDF_Dictionary *pDict = pObj->GetDict(); 932 if (pObj->GetType() == PDFOBJ_STREAM) { 933 if (pDict && pDict->GetString(FX_BSTRC("Type")) == FX_BSTRC("XRef")) { 934 return 0; 935 } 936 return 1; 937 } 938 if (pDict) { 939 if (pDict == m_pDocument->m_pRootDict || pDict == m_pEncryptDict) { 940 return 1; 941 } 942 if (IsSignatureDict(pDict)) { 943 return 1; 944 } 945 if (pDict->GetString(FX_BSTRC("Type")) == FX_BSTRC("Page")) { 946 return 1; 947 } 948 } 949 m_pXRefStream->AddObjectNumberToIndexArray(objnum); 950 if (m_pXRefStream->CompressIndirectObject(objnum, pObj, this) < 0) { 951 return -1; 952 } 953 if (!_IsXRefNeedEnd(m_pXRefStream, m_dwFlags)) { 954 return 0; 955 } 956 if (!m_pXRefStream->End(this)) { 957 return -1; 958 } 959 if (!m_pXRefStream->Start()) { 960 return -1; 961 } 962 return 0; 963 } 964 FX_INT32 CPDF_Creator::WriteIndirectObjectToStream(FX_DWORD objnum, FX_LPCBYTE pBuffer, FX_DWORD dwSize) 965 { 966 if (!m_pXRefStream) { 967 return 1; 968 } 969 m_pXRefStream->AddObjectNumberToIndexArray(objnum); 970 FX_INT32 iRet = m_pXRefStream->CompressIndirectObject(objnum, pBuffer, dwSize, this); 971 if (iRet < 1) { 972 return iRet; 973 } 974 if (!_IsXRefNeedEnd(m_pXRefStream, m_dwFlags)) { 975 return 0; 976 } 977 if (!m_pXRefStream->End(this)) { 978 return -1; 979 } 980 if (!m_pXRefStream->Start()) { 981 return -1; 982 } 983 return 0; 984 } 985 FX_INT32 CPDF_Creator::AppendObjectNumberToXRef(FX_DWORD objnum) 986 { 987 if (!m_pXRefStream) { 988 return 1; 989 } 990 m_pXRefStream->AddObjectNumberToIndexArray(objnum); 991 if (!_IsXRefNeedEnd(m_pXRefStream, m_dwFlags)) { 992 return 0; 993 } 994 if (!m_pXRefStream->End(this)) { 995 return -1; 996 } 997 if (!m_pXRefStream->Start()) { 998 return -1; 999 } 1000 return 0; 1001 } 1002 FX_INT32 CPDF_Creator::WriteStream(const CPDF_Object* pStream, FX_DWORD objnum, CPDF_CryptoHandler* pCrypto) 1003 { 1004 CPDF_FlateEncoder encoder; 1005 encoder.Initialize((CPDF_Stream*)pStream, pStream == m_pMetadata ? FALSE : m_bCompress); 1006 CPDF_Encryptor encryptor; 1007 if(!encryptor.Initialize(pCrypto, objnum, encoder.m_pData, encoder.m_dwSize)) { 1008 return -1; 1009 } 1010 if ((FX_DWORD)encoder.m_pDict->GetInteger(FX_BSTRC("Length")) != encryptor.m_dwSize) { 1011 encoder.CloneDict(); 1012 encoder.m_pDict->SetAtInteger(FX_BSTRC("Length"), encryptor.m_dwSize); 1013 } 1014 if (WriteDirectObj(objnum, encoder.m_pDict) < 0) { 1015 return -1; 1016 } 1017 int len = m_File.AppendString(FX_BSTRC("stream\r\n")); 1018 if (len < 0) { 1019 return -1; 1020 } 1021 m_Offset += len; 1022 if (m_File.AppendBlock(encryptor.m_pData, encryptor.m_dwSize) < 0) { 1023 return -1; 1024 } 1025 m_Offset += encryptor.m_dwSize; 1026 if ((len = m_File.AppendString(FX_BSTRC("\r\nendstream"))) < 0) { 1027 return -1; 1028 } 1029 m_Offset += len; 1030 return 1; 1031 } 1032 FX_INT32 CPDF_Creator::WriteIndirectObj(FX_DWORD objnum, const CPDF_Object* pObj) 1033 { 1034 FX_INT32 len = m_File.AppendDWord(objnum); 1035 if (len < 0) { 1036 return -1; 1037 } 1038 m_Offset += len; 1039 if ((len = m_File.AppendString(FX_BSTRC(" 0 obj\r\n"))) < 0) { 1040 return -1; 1041 } 1042 m_Offset += len; 1043 if (pObj->GetType() == PDFOBJ_STREAM) { 1044 CPDF_CryptoHandler *pHandler = NULL; 1045 pHandler = (pObj == m_pMetadata && !m_bEncryptMetadata) ? NULL : m_pCryptoHandler; 1046 if (WriteStream(pObj, objnum, pHandler) < 0) { 1047 return -1; 1048 } 1049 } else { 1050 if (WriteDirectObj(objnum, pObj) < 0) { 1051 return -1; 1052 } 1053 } 1054 if ((len = m_File.AppendString(FX_BSTRC("\r\nendobj\r\n"))) < 0) { 1055 return -1; 1056 } 1057 m_Offset += len; 1058 if (AppendObjectNumberToXRef(objnum) < 0) { 1059 return -1; 1060 } 1061 return 0; 1062 } 1063 FX_INT32 CPDF_Creator::WriteIndirectObj(const CPDF_Object* pObj) 1064 { 1065 FX_INT32 iRet = WriteIndirectObjectToStream(pObj); 1066 if (iRet < 1) { 1067 return iRet; 1068 } 1069 return WriteIndirectObj(pObj->GetObjNum(), pObj); 1070 } 1071 FX_INT32 CPDF_Creator::WriteDirectObj(FX_DWORD objnum, const CPDF_Object* pObj, FX_BOOL bEncrypt) 1072 { 1073 FX_INT32 len = 0; 1074 if (pObj == NULL) { 1075 if (m_File.AppendString(FX_BSTRC(" null")) < 0) { 1076 return -1; 1077 } 1078 m_Offset += 5; 1079 return 1; 1080 } 1081 switch (pObj->GetType()) { 1082 case PDFOBJ_NULL: 1083 if (m_File.AppendString(FX_BSTRC(" null")) < 0) { 1084 return -1; 1085 } 1086 m_Offset += 5; 1087 break; 1088 case PDFOBJ_BOOLEAN: 1089 case PDFOBJ_NUMBER: 1090 if (m_File.AppendString(FX_BSTRC(" ")) < 0) { 1091 return -1; 1092 } 1093 if ((len = m_File.AppendString(pObj->GetString())) < 0) { 1094 return -1; 1095 } 1096 m_Offset += len + 1; 1097 break; 1098 case PDFOBJ_STRING: { 1099 CFX_ByteString str = pObj->GetString(); 1100 FX_BOOL bHex = ((CPDF_String*)pObj)->IsHex(); 1101 if (m_pCryptoHandler == NULL || !bEncrypt) { 1102 CFX_ByteString content = PDF_EncodeString(str, bHex); 1103 if ((len = m_File.AppendString(content)) < 0) { 1104 return -1; 1105 } 1106 m_Offset += len; 1107 break; 1108 } 1109 CPDF_Encryptor encryptor; 1110 encryptor.Initialize(m_pCryptoHandler, objnum, (FX_LPBYTE)(FX_LPCSTR)str, str.GetLength()); 1111 CFX_ByteString content = PDF_EncodeString(CFX_ByteString((FX_LPCSTR)encryptor.m_pData, encryptor.m_dwSize), bHex); 1112 if ((len = m_File.AppendString(content)) < 0) { 1113 return -1; 1114 } 1115 m_Offset += len; 1116 break; 1117 } 1118 case PDFOBJ_STREAM: { 1119 CPDF_FlateEncoder encoder; 1120 encoder.Initialize((CPDF_Stream*)pObj, m_bCompress); 1121 CPDF_Encryptor encryptor; 1122 CPDF_CryptoHandler* pHandler = m_pCryptoHandler; 1123 encryptor.Initialize(pHandler, objnum, encoder.m_pData, encoder.m_dwSize); 1124 if ((FX_DWORD)encoder.m_pDict->GetInteger(FX_BSTRC("Length")) != encryptor.m_dwSize) { 1125 encoder.CloneDict(); 1126 encoder.m_pDict->SetAtInteger(FX_BSTRC("Length"), encryptor.m_dwSize); 1127 } 1128 if (WriteDirectObj(objnum, encoder.m_pDict) < 0) { 1129 return -1; 1130 } 1131 if ((len = m_File.AppendString(FX_BSTRC("stream\r\n"))) < 0) { 1132 return -1; 1133 } 1134 m_Offset += len; 1135 if (m_File.AppendBlock(encryptor.m_pData, encryptor.m_dwSize) < 0) { 1136 return -1; 1137 } 1138 m_Offset += encryptor.m_dwSize; 1139 if ((len = m_File.AppendString(FX_BSTRC("\r\nendstream"))) < 0) { 1140 return -1; 1141 } 1142 m_Offset += len; 1143 break; 1144 } 1145 case PDFOBJ_NAME: { 1146 if (m_File.AppendString(FX_BSTRC("/")) < 0) { 1147 return -1; 1148 } 1149 CFX_ByteString str = pObj->GetString(); 1150 if ((len = m_File.AppendString(PDF_NameEncode(str))) < 0) { 1151 return -1; 1152 } 1153 m_Offset += len + 1; 1154 break; 1155 } 1156 case PDFOBJ_REFERENCE: { 1157 if (m_File.AppendString(FX_BSTRC(" ")) < 0) { 1158 return -1; 1159 } 1160 CPDF_Reference* p = (CPDF_Reference*)pObj; 1161 if ((len = m_File.AppendDWord(p->GetRefObjNum())) < 0) { 1162 return -1; 1163 } 1164 if (m_File.AppendString(FX_BSTRC(" 0 R")) < 0) { 1165 return -1; 1166 } 1167 m_Offset += len + 5; 1168 break; 1169 } 1170 case PDFOBJ_ARRAY: { 1171 if (m_File.AppendString(FX_BSTRC("[")) < 0) { 1172 return -1; 1173 } 1174 m_Offset += 1; 1175 CPDF_Array* p = (CPDF_Array*)pObj; 1176 for (FX_DWORD i = 0; i < p->GetCount(); i ++) { 1177 CPDF_Object* pElement = p->GetElement(i); 1178 if (pElement->GetObjNum()) { 1179 if (m_File.AppendString(FX_BSTRC(" ")) < 0) { 1180 return -1; 1181 } 1182 if ((len = m_File.AppendDWord(pElement->GetObjNum())) < 0) { 1183 return -1; 1184 } 1185 if (m_File.AppendString(FX_BSTRC(" 0 R")) < 0) { 1186 return -1; 1187 } 1188 m_Offset += len + 5; 1189 } else { 1190 if (WriteDirectObj(objnum, pElement) < 0) { 1191 return -1; 1192 } 1193 } 1194 } 1195 if (m_File.AppendString(FX_BSTRC("]")) < 0) { 1196 return -1; 1197 } 1198 m_Offset += 1; 1199 break; 1200 } 1201 case PDFOBJ_DICTIONARY: { 1202 if (m_pCryptoHandler == NULL || pObj == m_pEncryptDict) { 1203 return PDF_CreatorAppendObject(pObj, &m_File, m_Offset); 1204 } 1205 if (m_File.AppendString(FX_BSTRC("<<")) < 0) { 1206 return -1; 1207 } 1208 m_Offset += 2; 1209 CPDF_Dictionary* p = (CPDF_Dictionary*)pObj; 1210 FX_BOOL bSignDict = IsSignatureDict(p); 1211 FX_POSITION pos = p->GetStartPos(); 1212 while (pos) { 1213 FX_BOOL bSignValue = FALSE; 1214 CFX_ByteString key; 1215 CPDF_Object* pValue = p->GetNextElement(pos, key); 1216 if (m_File.AppendString(FX_BSTRC("/")) < 0) { 1217 return -1; 1218 } 1219 if ((len = m_File.AppendString(PDF_NameEncode(key))) < 0) { 1220 return -1; 1221 } 1222 m_Offset += len + 1; 1223 if (bSignDict && key == FX_BSTRC("Contents")) { 1224 bSignValue = TRUE; 1225 } 1226 if (pValue->GetObjNum()) { 1227 if (m_File.AppendString(FX_BSTRC(" ")) < 0) { 1228 return -1; 1229 } 1230 if ((len = m_File.AppendDWord(pValue->GetObjNum())) < 0) { 1231 return -1; 1232 } 1233 if (m_File.AppendString(FX_BSTRC(" 0 R ")) < 0) { 1234 return -1; 1235 } 1236 m_Offset += len + 6; 1237 } else { 1238 if (WriteDirectObj(objnum, pValue, !bSignValue) < 0) { 1239 return -1; 1240 } 1241 } 1242 } 1243 if (m_File.AppendString(FX_BSTRC(">>")) < 0) { 1244 return -1; 1245 } 1246 m_Offset += 2; 1247 break; 1248 } 1249 } 1250 return 1; 1251 } 1252 FX_INT32 CPDF_Creator::WriteOldIndirectObject(FX_DWORD objnum) 1253 { 1254 if(m_pParser->m_V5Type[objnum] == 0 || m_pParser->m_V5Type[objnum] == 255) { 1255 return 0; 1256 } 1257 m_ObjectOffset[objnum] = m_Offset; 1258 FX_LPVOID valuetemp = NULL; 1259 FX_BOOL bExistInMap = m_pDocument->m_IndirectObjs.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, valuetemp); 1260 FX_BOOL bObjStm = (m_pParser->m_V5Type[objnum] == 2) && m_pEncryptDict && !m_pXRefStream; 1261 if(m_pParser->m_bVersionUpdated || m_bSecurityChanged || bExistInMap || bObjStm) { 1262 CPDF_Object* pObj = m_pDocument->GetIndirectObject(objnum); 1263 if (pObj == NULL) { 1264 m_ObjectOffset[objnum] = 0; 1265 m_ObjectSize[objnum] = 0; 1266 return 0; 1267 } 1268 if (WriteIndirectObj(pObj)) { 1269 return -1; 1270 } 1271 if (!bExistInMap) { 1272 m_pDocument->ReleaseIndirectObject(objnum); 1273 } 1274 } else { 1275 FX_BYTE* pBuffer; 1276 FX_DWORD size; 1277 m_pParser->GetIndirectBinary(objnum, pBuffer, size); 1278 if (pBuffer == NULL) { 1279 return 0; 1280 } 1281 if (m_pParser->m_V5Type[objnum] == 2) { 1282 if (m_pXRefStream) { 1283 if (WriteIndirectObjectToStream(objnum, pBuffer, size) < 0) { 1284 FX_Free(pBuffer); 1285 return -1; 1286 } 1287 } else { 1288 FX_INT32 len = m_File.AppendDWord(objnum); 1289 if (len < 0) { 1290 return -1; 1291 } 1292 if (m_File.AppendString(FX_BSTRC(" 0 obj ")) < 0) { 1293 return -1; 1294 } 1295 m_Offset += len + 7; 1296 if (m_File.AppendBlock(pBuffer, size) < 0) { 1297 return -1; 1298 } 1299 m_Offset += size; 1300 if (m_File.AppendString(FX_BSTRC("\r\nendobj\r\n")) < 0) { 1301 return -1; 1302 } 1303 m_Offset += 10; 1304 } 1305 } else { 1306 if (m_File.AppendBlock(pBuffer, size) < 0) { 1307 return -1; 1308 } 1309 m_Offset += size; 1310 if(AppendObjectNumberToXRef(objnum) < 0) { 1311 return -1; 1312 } 1313 } 1314 FX_Free(pBuffer); 1315 } 1316 return 1; 1317 } 1318 FX_INT32 CPDF_Creator::WriteOldObjs(IFX_Pause *pPause) 1319 { 1320 FX_DWORD nOldSize = m_pParser->m_CrossRef.GetSize(); 1321 FX_DWORD objnum = (FX_DWORD)(FX_UINTPTR)m_Pos; 1322 for(; objnum < nOldSize; objnum ++) { 1323 FX_INT32 iRet = WriteOldIndirectObject(objnum); 1324 if (!iRet) { 1325 continue; 1326 } 1327 if (iRet < 0) { 1328 return iRet; 1329 } 1330 m_ObjectSize[objnum] = (FX_DWORD)(m_Offset - m_ObjectOffset[objnum]); 1331 if (pPause && pPause->NeedToPauseNow()) { 1332 m_Pos = (FX_LPVOID)(FX_UINTPTR)(objnum + 1); 1333 return 1; 1334 } 1335 } 1336 return 0; 1337 } 1338 FX_INT32 CPDF_Creator::WriteNewObjs(FX_BOOL bIncremental, IFX_Pause *pPause) 1339 { 1340 FX_INT32 iCount = m_NewObjNumArray.GetSize(); 1341 FX_INT32 index = (FX_INT32)(FX_UINTPTR)m_Pos; 1342 while (index < iCount) { 1343 FX_DWORD objnum = m_NewObjNumArray.ElementAt(index); 1344 CPDF_Object *pObj = NULL; 1345 m_pDocument->m_IndirectObjs.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, (FX_LPVOID&)pObj); 1346 if (NULL == pObj) { 1347 ++index; 1348 continue; 1349 } 1350 m_ObjectOffset[objnum] = m_Offset; 1351 if (WriteIndirectObj(pObj)) { 1352 return -1; 1353 } 1354 m_ObjectSize[objnum] = (FX_DWORD)(m_Offset - m_ObjectOffset[objnum]); 1355 index++; 1356 if (pPause && pPause->NeedToPauseNow()) { 1357 m_Pos = (FX_POSITION)(FX_UINTPTR)index; 1358 return 1; 1359 } 1360 } 1361 return 0; 1362 } 1363 void CPDF_Creator::InitOldObjNumOffsets() 1364 { 1365 if (!m_pParser) { 1366 return; 1367 } 1368 FX_DWORD j = 0; 1369 FX_DWORD dwStart = 0; 1370 FX_DWORD dwEnd = m_pParser->GetLastObjNum(); 1371 while (dwStart <= dwEnd) { 1372 while (dwStart <= dwEnd && (m_pParser->m_V5Type[dwStart] == 0 || m_pParser->m_V5Type[dwStart] == 255)) { 1373 dwStart++; 1374 } 1375 if (dwStart > dwEnd) { 1376 break; 1377 } 1378 j = dwStart; 1379 while (j <= dwEnd && m_pParser->m_V5Type[j] != 0 && m_pParser->m_V5Type[j] != 255) { 1380 j++; 1381 } 1382 m_ObjectOffset.Add(dwStart, j - dwStart); 1383 m_ObjectSize.Add(dwStart, j - dwStart); 1384 dwStart = j; 1385 } 1386 } 1387 void CPDF_Creator::InitNewObjNumOffsets() 1388 { 1389 FX_BOOL bIncremental = (m_dwFlags & FPDFCREATE_INCREMENTAL) != 0; 1390 FX_BOOL bNoOriginal = (m_dwFlags & FPDFCREATE_NO_ORIGINAL) != 0; 1391 FX_DWORD nOldSize = m_pParser ? m_pParser->m_CrossRef.GetSize() : 0; 1392 FX_POSITION pos = m_pDocument->m_IndirectObjs.GetStartPosition(); 1393 while (pos) { 1394 size_t key = 0; 1395 CPDF_Object* pObj; 1396 m_pDocument->m_IndirectObjs.GetNextAssoc(pos, (FX_LPVOID&)key, (FX_LPVOID&)pObj); 1397 FX_DWORD objnum = (FX_DWORD)key; 1398 if (pObj->GetObjNum() == -1) { 1399 continue; 1400 } 1401 if (bIncremental) { 1402 if (!pObj->IsModified()) { 1403 continue; 1404 } 1405 } else { 1406 if (objnum < nOldSize && m_pParser->m_V5Type[objnum] != 0) { 1407 continue; 1408 } 1409 } 1410 AppendNewObjNum(objnum); 1411 } 1412 FX_INT32 iCount = m_NewObjNumArray.GetSize(); 1413 if (iCount == 0) { 1414 return; 1415 } 1416 FX_INT32 i = 0; 1417 FX_DWORD dwStartObjNum = 0; 1418 FX_BOOL bCrossRefValid = m_pParser && m_pParser->GetLastXRefOffset() > 0; 1419 while (i < iCount) { 1420 dwStartObjNum = m_NewObjNumArray.ElementAt(i); 1421 if ((bIncremental && (bNoOriginal || bCrossRefValid)) || !m_ObjectOffset.GetPtrAt(dwStartObjNum)) { 1422 break; 1423 } 1424 i++; 1425 } 1426 if (i >= iCount) { 1427 return; 1428 } 1429 FX_DWORD dwLastObjNum = dwStartObjNum; 1430 i++; 1431 FX_BOOL bNewStart = FALSE; 1432 for (; i < iCount; i++) { 1433 FX_DWORD dwCurObjNum = m_NewObjNumArray.ElementAt(i); 1434 FX_BOOL bExist = (dwCurObjNum < nOldSize && m_ObjectOffset.GetPtrAt(dwCurObjNum) != NULL); 1435 if (bExist || dwCurObjNum - dwLastObjNum > 1) { 1436 if (!bNewStart) { 1437 m_ObjectOffset.Add(dwStartObjNum, dwLastObjNum - dwStartObjNum + 1); 1438 m_ObjectSize.Add(dwStartObjNum, dwLastObjNum - dwStartObjNum + 1); 1439 } 1440 dwStartObjNum = dwCurObjNum; 1441 } 1442 if (bNewStart) { 1443 dwStartObjNum = dwCurObjNum; 1444 } 1445 bNewStart = bExist; 1446 dwLastObjNum = dwCurObjNum; 1447 } 1448 m_ObjectOffset.Add(dwStartObjNum, dwLastObjNum - dwStartObjNum + 1); 1449 m_ObjectSize.Add(dwStartObjNum, dwLastObjNum - dwStartObjNum + 1); 1450 } 1451 void CPDF_Creator::AppendNewObjNum(FX_DWORD objbum) 1452 { 1453 FX_INT32 iStart = 0, iFind = 0; 1454 FX_INT32 iEnd = m_NewObjNumArray.GetUpperBound(); 1455 while (iStart <= iEnd) { 1456 FX_INT32 iMid = (iStart + iEnd) / 2; 1457 FX_DWORD dwMid = m_NewObjNumArray.ElementAt(iMid); 1458 if (objbum < dwMid) { 1459 iEnd = iMid - 1; 1460 } else { 1461 if (iMid == iEnd) { 1462 iFind = iMid + 1; 1463 break; 1464 } 1465 FX_DWORD dwNext = m_NewObjNumArray.ElementAt(iMid + 1); 1466 if (objbum < dwNext) { 1467 iFind = iMid + 1; 1468 break; 1469 } 1470 iStart = iMid + 1; 1471 } 1472 } 1473 m_NewObjNumArray.InsertAt(iFind, objbum); 1474 } 1475 FX_INT32 CPDF_Creator::WriteDoc_Stage1(IFX_Pause *pPause) 1476 { 1477 FXSYS_assert(m_iStage > -1 || m_iStage < 20); 1478 if (m_iStage == 0) { 1479 if (m_pParser == NULL) { 1480 m_dwFlags &= ~FPDFCREATE_INCREMENTAL; 1481 } 1482 if (m_bSecurityChanged && (m_dwFlags & FPDFCREATE_NO_ORIGINAL) == 0) { 1483 m_dwFlags &= ~FPDFCREATE_INCREMENTAL; 1484 } 1485 m_pMetadata = m_pDocument->GetRoot()->GetElementValue(FX_BSTRC("Metadata")); 1486 if (m_dwFlags & FPDFCREATE_OBJECTSTREAM) { 1487 m_pXRefStream = FX_NEW CPDF_XRefStream; 1488 m_pXRefStream->Start(); 1489 if ((m_dwFlags & FPDFCREATE_INCREMENTAL) != 0 && m_pParser) { 1490 FX_FILESIZE prev = m_pParser->GetLastXRefOffset(); 1491 m_pXRefStream->m_PrevOffset = prev; 1492 } 1493 } 1494 m_iStage = 10; 1495 } 1496 if (m_iStage == 10) { 1497 if ((m_dwFlags & FPDFCREATE_INCREMENTAL) == 0) { 1498 if (m_File.AppendString(FX_BSTRC("%PDF-1.")) < 0) { 1499 return -1; 1500 } 1501 m_Offset += 7; 1502 FX_INT32 version = 7; 1503 if (m_FileVersion) { 1504 version = m_FileVersion; 1505 } else if (m_pParser) { 1506 version = m_pParser->GetFileVersion(); 1507 } 1508 FX_INT32 len = m_File.AppendDWord(version % 10); 1509 if (len < 0) { 1510 return -1; 1511 } 1512 m_Offset += len; 1513 if ((len = m_File.AppendString(FX_BSTRC("\r\n%\xA1\xB3\xC5\xD7\r\n"))) < 0) { 1514 return -1; 1515 } 1516 m_Offset += len; 1517 InitOldObjNumOffsets(); 1518 m_iStage = 20; 1519 } else { 1520 IFX_FileRead* pSrcFile = m_pParser->GetFileAccess(); 1521 m_Offset = pSrcFile->GetSize(); 1522 m_Pos = (FX_LPVOID)(FX_UINTPTR)m_Offset; 1523 m_iStage = 15; 1524 } 1525 } 1526 if (m_iStage == 15) { 1527 if ((m_dwFlags & FPDFCREATE_NO_ORIGINAL) == 0 && m_Pos) { 1528 IFX_FileRead* pSrcFile = m_pParser->GetFileAccess(); 1529 FX_BYTE buffer[4096]; 1530 FX_DWORD src_size = (FX_DWORD)(FX_UINTPTR)m_Pos; 1531 while (src_size) { 1532 FX_DWORD block_size = src_size > 4096 ? 4096 : src_size; 1533 if (!pSrcFile->ReadBlock(buffer, m_Offset - src_size, block_size)) { 1534 return -1; 1535 } 1536 if (m_File.AppendBlock(buffer, block_size) < 0) { 1537 return -1; 1538 } 1539 src_size -= block_size; 1540 if (pPause && pPause->NeedToPauseNow()) { 1541 m_Pos = (FX_LPVOID)(FX_UINTPTR)src_size; 1542 return 1; 1543 } 1544 } 1545 } 1546 if ((m_dwFlags & FPDFCREATE_NO_ORIGINAL) == 0 && m_pParser->GetLastXRefOffset() == 0) { 1547 InitOldObjNumOffsets(); 1548 FX_DWORD dwEnd = m_pParser->GetLastObjNum(); 1549 FX_BOOL bObjStm = (m_dwFlags & FPDFCREATE_OBJECTSTREAM) != 0; 1550 for (FX_DWORD objnum = 0; objnum <= dwEnd; objnum++) { 1551 if (m_pParser->m_V5Type[objnum] == 0 || m_pParser->m_V5Type[objnum] == 255) { 1552 continue; 1553 } 1554 m_ObjectOffset[objnum] = m_pParser->m_CrossRef[objnum]; 1555 if (bObjStm) { 1556 m_pXRefStream->AddObjectNumberToIndexArray(objnum); 1557 } 1558 } 1559 if (bObjStm) { 1560 m_pXRefStream->EndXRefStream(this); 1561 m_pXRefStream->Start(); 1562 } 1563 } 1564 m_iStage = 20; 1565 } 1566 InitNewObjNumOffsets(); 1567 return m_iStage; 1568 } 1569 FX_INT32 CPDF_Creator::WriteDoc_Stage2(IFX_Pause *pPause) 1570 { 1571 FXSYS_assert(m_iStage >= 20 || m_iStage < 30); 1572 if (m_iStage == 20) { 1573 if ((m_dwFlags & FPDFCREATE_INCREMENTAL) == 0 && m_pParser) { 1574 m_Pos = (FX_LPVOID)(FX_UINTPTR)0; 1575 m_iStage = 21; 1576 } else { 1577 m_iStage = 25; 1578 } 1579 } 1580 if (m_iStage == 21) { 1581 FX_INT32 iRet = WriteOldObjs(pPause); 1582 if (iRet) { 1583 return iRet; 1584 } 1585 m_iStage = 25; 1586 } 1587 if (m_iStage == 25) { 1588 m_Pos = (FX_LPVOID)(FX_UINTPTR)0; 1589 m_iStage = 26; 1590 } 1591 if (m_iStage == 26) { 1592 FX_INT32 iRet = WriteNewObjs((m_dwFlags & FPDFCREATE_INCREMENTAL) != 0, pPause); 1593 if (iRet) { 1594 return iRet; 1595 } 1596 m_iStage = 27; 1597 } 1598 if (m_iStage == 27) { 1599 if (NULL != m_pEncryptDict && 0 == m_pEncryptDict->GetObjNum()) { 1600 m_dwLastObjNum += 1; 1601 FX_FILESIZE saveOffset = m_Offset; 1602 if (WriteIndirectObj(m_dwLastObjNum, m_pEncryptDict) < 0) { 1603 return -1; 1604 } 1605 m_ObjectOffset.Add(m_dwLastObjNum, 1); 1606 m_ObjectOffset[m_dwLastObjNum] = saveOffset; 1607 m_ObjectSize.Add(m_dwLastObjNum, 1); 1608 m_ObjectSize[m_dwLastObjNum] = m_Offset - saveOffset; 1609 m_dwEnryptObjNum = m_dwLastObjNum; 1610 if (m_dwFlags & FPDFCREATE_INCREMENTAL) { 1611 m_NewObjNumArray.Add(m_dwLastObjNum); 1612 } 1613 } 1614 m_iStage = 80; 1615 } 1616 return m_iStage; 1617 } 1618 FX_INT32 CPDF_Creator::WriteDoc_Stage3(IFX_Pause *pPause) 1619 { 1620 FXSYS_assert(m_iStage >= 80 || m_iStage < 90); 1621 FX_DWORD dwLastObjNum = m_dwLastObjNum; 1622 if (m_iStage == 80) { 1623 m_XrefStart = m_Offset; 1624 if (m_dwFlags & FPDFCREATE_OBJECTSTREAM) { 1625 m_pXRefStream->End(this, TRUE); 1626 m_XrefStart = m_pXRefStream->m_PrevOffset; 1627 m_iStage = 90; 1628 } else if ((m_dwFlags & FPDFCREATE_INCREMENTAL) == 0 || !m_pParser->IsXRefStream()) { 1629 if ((m_dwFlags & FPDFCREATE_INCREMENTAL) == 0 || m_pParser->GetLastXRefOffset() == 0) { 1630 CFX_ByteString str; 1631 str = m_ObjectOffset.GetPtrAt(1) ? FX_BSTRC("xref\r\n") : FX_BSTRC("xref\r\n0 1\r\n0000000000 65536 f\r\n"); 1632 if (m_File.AppendString(str) < 0) { 1633 return -1; 1634 } 1635 m_Pos = (FX_LPVOID)(FX_UINTPTR)1; 1636 m_iStage = 81; 1637 } else { 1638 if (m_File.AppendString(FX_BSTRC("xref\r\n")) < 0) { 1639 return -1; 1640 } 1641 m_Pos = (FX_LPVOID)(FX_UINTPTR)0; 1642 m_iStage = 82; 1643 } 1644 } else { 1645 m_iStage = 90; 1646 } 1647 } 1648 if (m_iStage == 81) { 1649 CFX_ByteString str; 1650 FX_DWORD i = (FX_DWORD)(FX_UINTPTR)m_Pos, j; 1651 while (i <= dwLastObjNum) { 1652 while (i <= dwLastObjNum && !m_ObjectOffset.GetPtrAt(i)) { 1653 i++; 1654 } 1655 if (i > dwLastObjNum) { 1656 break; 1657 } 1658 j = i; 1659 while (j <= dwLastObjNum && m_ObjectOffset.GetPtrAt(j)) { 1660 j++; 1661 } 1662 if (i == 1) { 1663 str.Format("0 %d\r\n0000000000 65536 f\r\n", j); 1664 } else { 1665 str.Format("%d %d\r\n", i, j - i); 1666 } 1667 if (m_File.AppendBlock((FX_LPCSTR)str, str.GetLength()) < 0) { 1668 return -1; 1669 } 1670 while (i < j) { 1671 str.Format("%010d 00000 n\r\n", m_ObjectOffset[i ++]); 1672 if (m_File.AppendBlock((FX_LPCSTR)str, str.GetLength()) < 0) { 1673 return -1; 1674 } 1675 } 1676 if (i > dwLastObjNum) { 1677 break; 1678 } 1679 if (pPause && pPause->NeedToPauseNow()) { 1680 m_Pos = (FX_LPVOID)(FX_UINTPTR)i; 1681 return 1; 1682 } 1683 } 1684 m_iStage = 90; 1685 } 1686 if (m_iStage == 82) { 1687 CFX_ByteString str; 1688 FX_INT32 iCount = m_NewObjNumArray.GetSize(); 1689 FX_INT32 i = (FX_INT32)(FX_UINTPTR)m_Pos; 1690 while (i < iCount) { 1691 FX_INT32 j = i; 1692 FX_DWORD objnum = m_NewObjNumArray.ElementAt(i); 1693 while (j < iCount) { 1694 if (++j == iCount) { 1695 break; 1696 } 1697 FX_DWORD dwCurrent = m_NewObjNumArray.ElementAt(j); 1698 if (dwCurrent - objnum > 1) { 1699 break; 1700 } 1701 objnum = dwCurrent; 1702 } 1703 objnum = m_NewObjNumArray.ElementAt(i); 1704 if (objnum == 1) { 1705 str.Format("0 %d\r\n0000000000 65536 f\r\n", j - i + 1); 1706 } else { 1707 str.Format("%d %d\r\n", objnum, j - i); 1708 } 1709 if (m_File.AppendBlock((FX_LPCSTR)str, str.GetLength()) < 0) { 1710 return -1; 1711 } 1712 while (i < j) { 1713 objnum = m_NewObjNumArray.ElementAt(i++); 1714 str.Format("%010d 00000 n\r\n", m_ObjectOffset[objnum]); 1715 if (m_File.AppendBlock((FX_LPCSTR)str, str.GetLength()) < 0) { 1716 return -1; 1717 } 1718 } 1719 if (pPause && (i % 100) == 0 && pPause->NeedToPauseNow()) { 1720 m_Pos = (FX_LPVOID)(FX_UINTPTR)i; 1721 return 1; 1722 } 1723 } 1724 m_iStage = 90; 1725 } 1726 return m_iStage; 1727 } 1728 static FX_INT32 _OutPutIndex(CFX_FileBufferArchive* pFile, FX_FILESIZE offset) 1729 { 1730 FXSYS_assert(pFile); 1731 if (sizeof(offset) > 4) { 1732 if (FX_GETBYTEOFFSET32(offset)) { 1733 if (pFile->AppendByte(FX_GETBYTEOFFSET56(offset)) < 0) { 1734 return -1; 1735 } 1736 if (pFile->AppendByte(FX_GETBYTEOFFSET48(offset)) < 0) { 1737 return -1; 1738 } 1739 if (pFile->AppendByte(FX_GETBYTEOFFSET40(offset)) < 0) { 1740 return -1; 1741 } 1742 if (pFile->AppendByte(FX_GETBYTEOFFSET32(offset)) < 0) { 1743 return -1; 1744 } 1745 } 1746 } 1747 if (pFile->AppendByte(FX_GETBYTEOFFSET24(offset)) < 0) { 1748 return -1; 1749 } 1750 if (pFile->AppendByte(FX_GETBYTEOFFSET16(offset)) < 0) { 1751 return -1; 1752 } 1753 if (pFile->AppendByte(FX_GETBYTEOFFSET8(offset)) < 0) { 1754 return -1; 1755 } 1756 if (pFile->AppendByte(FX_GETBYTEOFFSET0(offset)) < 0) { 1757 return -1; 1758 } 1759 if (pFile->AppendByte(0) < 0) { 1760 return -1; 1761 } 1762 return 0; 1763 } 1764 FX_INT32 CPDF_Creator::WriteDoc_Stage4(IFX_Pause *pPause) 1765 { 1766 FXSYS_assert(m_iStage >= 90); 1767 if ((m_dwFlags & FPDFCREATE_OBJECTSTREAM) == 0) { 1768 FX_BOOL bXRefStream = (m_dwFlags & FPDFCREATE_INCREMENTAL) != 0 && m_pParser->IsXRefStream(); 1769 if (!bXRefStream) { 1770 if (m_File.AppendString(FX_BSTRC("trailer\r\n<<")) < 0) { 1771 return -1; 1772 } 1773 } else { 1774 if (m_File.AppendDWord(m_pDocument->m_LastObjNum + 1) < 0) { 1775 return -1; 1776 } 1777 if (m_File.AppendString(FX_BSTRC(" 0 obj <<")) < 0) { 1778 return -1; 1779 } 1780 } 1781 if (m_pParser) { 1782 CPDF_Dictionary* p = m_pParser->m_pTrailer; 1783 FX_POSITION pos = p->GetStartPos(); 1784 while (pos) { 1785 CFX_ByteString key; 1786 CPDF_Object* pValue = p->GetNextElement(pos, key); 1787 if (key == FX_BSTRC("Encrypt") || key == FX_BSTRC("Size") || key == FX_BSTRC("Filter") || 1788 key == FX_BSTRC("Index") || key == FX_BSTRC("Length") || key == FX_BSTRC("Prev") || 1789 key == FX_BSTRC("W") || key == FX_BSTRC("XRefStm") || key == FX_BSTRC("ID")) { 1790 continue; 1791 } 1792 if (m_File.AppendString((FX_BSTRC("/"))) < 0) { 1793 return -1; 1794 } 1795 if (m_File.AppendString(PDF_NameEncode(key)) < 0) { 1796 return -1; 1797 } 1798 if (pValue->GetObjNum()) { 1799 if (m_File.AppendString(FX_BSTRC(" ")) < 0) { 1800 return -1; 1801 } 1802 if (m_File.AppendDWord(pValue->GetObjNum()) < 0) { 1803 return -1; 1804 } 1805 if (m_File.AppendString(FX_BSTRC(" 0 R ")) < 0) { 1806 return -1; 1807 } 1808 } else { 1809 FX_FILESIZE offset = 0; 1810 if (PDF_CreatorAppendObject(pValue, &m_File, offset) < 0) { 1811 return -1; 1812 } 1813 } 1814 } 1815 } else { 1816 if (m_File.AppendString(FX_BSTRC("\r\n/Root ")) < 0) { 1817 return -1; 1818 } 1819 if (m_File.AppendDWord(m_pDocument->m_pRootDict->GetObjNum()) < 0) { 1820 return -1; 1821 } 1822 if (m_File.AppendString(FX_BSTRC(" 0 R\r\n")) < 0) { 1823 return -1; 1824 } 1825 if (m_pDocument->m_pInfoDict) { 1826 if (m_File.AppendString(FX_BSTRC("/Info ")) < 0) { 1827 return -1; 1828 } 1829 if (m_File.AppendDWord(m_pDocument->m_pInfoDict->GetObjNum()) < 0) { 1830 return -1; 1831 } 1832 if (m_File.AppendString(FX_BSTRC(" 0 R\r\n")) < 0) { 1833 return -1; 1834 } 1835 } 1836 } 1837 if (m_pEncryptDict) { 1838 if (m_File.AppendString(FX_BSTRC("/Encrypt")) < 0) { 1839 return -1; 1840 } 1841 FX_DWORD dwObjNum = m_pEncryptDict->GetObjNum(); 1842 if (dwObjNum == 0) { 1843 dwObjNum = m_pDocument->GetLastObjNum() + 1; 1844 } 1845 if (m_File.AppendString(FX_BSTRC(" ")) < 0) { 1846 return -1; 1847 } 1848 if (m_File.AppendDWord(dwObjNum) < 0) { 1849 return -1; 1850 } 1851 if (m_File.AppendString(FX_BSTRC(" 0 R ")) < 0) { 1852 return -1; 1853 } 1854 } 1855 if (m_File.AppendString(FX_BSTRC("/Size ")) < 0) { 1856 return -1; 1857 } 1858 if (m_File.AppendDWord(m_dwLastObjNum + (bXRefStream ? 2 : 1)) < 0) { 1859 return -1; 1860 } 1861 if ((m_dwFlags & FPDFCREATE_INCREMENTAL) != 0) { 1862 FX_FILESIZE prev = m_pParser->GetLastXRefOffset(); 1863 if (prev) { 1864 if (m_File.AppendString(FX_BSTRC("/Prev ")) < 0) { 1865 return -1; 1866 } 1867 FX_CHAR offset_buf[20]; 1868 FXSYS_memset32(offset_buf, 0, sizeof(offset_buf)); 1869 FXSYS_i64toa(prev, offset_buf, 10); 1870 if (m_File.AppendBlock(offset_buf, FXSYS_strlen(offset_buf)) < 0) { 1871 return -1; 1872 } 1873 } 1874 } 1875 if (m_pIDArray) { 1876 if (m_File.AppendString((FX_BSTRC("/ID"))) < 0) { 1877 return -1; 1878 } 1879 FX_FILESIZE offset = 0; 1880 if (PDF_CreatorAppendObject(m_pIDArray, &m_File, offset) < 0) { 1881 return -1; 1882 } 1883 } 1884 if (!bXRefStream) { 1885 if (m_File.AppendString(FX_BSTRC(">>")) < 0) { 1886 return -1; 1887 } 1888 } else { 1889 if (m_File.AppendString(FX_BSTRC("/W[0 4 1]/Index[")) < 0) { 1890 return -1; 1891 } 1892 if ((m_dwFlags & FPDFCREATE_INCREMENTAL) != 0 && m_pParser && m_pParser->GetLastXRefOffset() == 0) { 1893 FX_DWORD i = 0; 1894 for (i = 0; i < m_dwLastObjNum; i++) { 1895 if (!m_ObjectOffset.GetPtrAt(i)) { 1896 continue; 1897 } 1898 if (m_File.AppendDWord(i) < 0) { 1899 return -1; 1900 } 1901 if (m_File.AppendString(FX_BSTRC(" 1 ")) < 0) { 1902 return -1; 1903 } 1904 } 1905 if (m_File.AppendString(FX_BSTRC("]/Length ")) < 0) { 1906 return -1; 1907 } 1908 if (m_File.AppendDWord(m_dwLastObjNum * 5) < 0) { 1909 return -1; 1910 } 1911 if (m_File.AppendString(FX_BSTRC(">>stream\r\n")) < 0) { 1912 return -1; 1913 } 1914 for (i = 0; i < m_dwLastObjNum; i++) { 1915 FX_FILESIZE* offset = m_ObjectOffset.GetPtrAt(i); 1916 if (!offset) { 1917 continue; 1918 } 1919 _OutPutIndex(&m_File, *offset); 1920 } 1921 } else { 1922 int count = m_NewObjNumArray.GetSize(); 1923 FX_INT32 i = 0; 1924 for (i = 0; i < count; i++) { 1925 FX_DWORD objnum = m_NewObjNumArray.ElementAt(i); 1926 if (m_File.AppendDWord(objnum) < 0) { 1927 return -1; 1928 } 1929 if (m_File.AppendString(FX_BSTRC(" 1 ")) < 0) { 1930 return -1; 1931 } 1932 } 1933 if (m_File.AppendString(FX_BSTRC("]/Length ")) < 0) { 1934 return -1; 1935 } 1936 if (m_File.AppendDWord(count * 5) < 0) { 1937 return -1; 1938 } 1939 if (m_File.AppendString(FX_BSTRC(">>stream\r\n")) < 0) { 1940 return -1; 1941 } 1942 for (i = 0; i < count; i++) { 1943 FX_DWORD objnum = m_NewObjNumArray.ElementAt(i); 1944 FX_FILESIZE offset = m_ObjectOffset[objnum]; 1945 _OutPutIndex(&m_File, offset); 1946 } 1947 } 1948 if (m_File.AppendString(FX_BSTRC("\r\nendstream")) < 0) { 1949 return -1; 1950 } 1951 } 1952 } 1953 if (m_File.AppendString(FX_BSTRC("\r\nstartxref\r\n")) < 0) { 1954 return -1; 1955 } 1956 FX_CHAR offset_buf[20]; 1957 FXSYS_memset32(offset_buf, 0, sizeof(offset_buf)); 1958 FXSYS_i64toa(m_XrefStart, offset_buf, 10); 1959 if (m_File.AppendBlock(offset_buf, FXSYS_strlen(offset_buf)) < 0) { 1960 return -1; 1961 } 1962 if (m_File.AppendString(FX_BSTRC("\r\n%%EOF\r\n")) < 0) { 1963 return -1; 1964 } 1965 m_File.Flush(); 1966 return m_iStage = 100; 1967 } 1968 void CPDF_Creator::Clear() 1969 { 1970 if (m_pXRefStream) { 1971 delete m_pXRefStream; 1972 m_pXRefStream = NULL; 1973 } 1974 m_File.Clear(); 1975 m_NewObjNumArray.RemoveAll(); 1976 if (m_pIDArray) { 1977 m_pIDArray->Release(); 1978 m_pIDArray = NULL; 1979 } 1980 } 1981 FX_BOOL CPDF_Creator::Create(FX_LPCSTR filename, FX_DWORD flags) 1982 { 1983 if (!m_File.AttachFile(filename)) { 1984 return FALSE; 1985 } 1986 FX_BOOL bRet = Create(flags); 1987 if (!bRet || !(flags & FPDFCREATE_PROGRESSIVE)) { 1988 Clear(); 1989 } 1990 return bRet; 1991 } 1992 FX_BOOL CPDF_Creator::Create(FX_LPCWSTR filename, FX_DWORD flags) 1993 { 1994 if (!m_File.AttachFile(filename)) { 1995 return FALSE; 1996 } 1997 FX_BOOL bRet = Create(flags); 1998 if (!bRet || !(flags & FPDFCREATE_PROGRESSIVE)) { 1999 Clear(); 2000 } 2001 return bRet; 2002 } 2003 FX_BOOL CPDF_Creator::Create(IFX_StreamWrite* pFile, FX_DWORD flags) 2004 { 2005 if (!pFile) { 2006 return FALSE; 2007 } 2008 if (!m_File.AttachFile(pFile, FALSE)) { 2009 return FALSE; 2010 } 2011 return Create(flags); 2012 } 2013 FX_BOOL CPDF_Creator::Create(FX_DWORD flags) 2014 { 2015 m_dwFlags = flags; 2016 m_iStage = 0; 2017 m_Offset = 0; 2018 m_dwLastObjNum = m_pDocument->GetLastObjNum(); 2019 m_ObjectOffset.Clear(); 2020 m_ObjectSize.Clear(); 2021 m_NewObjNumArray.RemoveAll(); 2022 InitID(); 2023 if (flags & FPDFCREATE_PROGRESSIVE) { 2024 return TRUE; 2025 } 2026 return Continue(NULL) > -1; 2027 } 2028 void CPDF_Creator::InitID(FX_BOOL bDefault ) 2029 { 2030 CPDF_Array* pOldIDArray = m_pParser ? m_pParser->GetIDArray() : NULL; 2031 FX_BOOL bNewId = !m_pIDArray; 2032 if (!m_pIDArray) { 2033 FX_LPDWORD pBuffer = NULL; 2034 m_pIDArray = CPDF_Array::Create(); 2035 CPDF_Object* pID1 = pOldIDArray->GetElement(0); 2036 if (pID1) { 2037 m_pIDArray->Add(pID1->Clone()); 2038 } else { 2039 pBuffer = FX_Alloc(FX_DWORD, 4); 2040 PDF_GenerateFileID((FX_DWORD)(FX_UINTPTR)this, m_dwLastObjNum, pBuffer); 2041 CFX_ByteStringC bsBuffer((FX_LPCBYTE)pBuffer, 4 * sizeof(FX_DWORD)); 2042 m_pIDArray->Add(CPDF_String::Create(bsBuffer, TRUE), m_pDocument); 2043 } 2044 if (pBuffer) { 2045 FX_Free(pBuffer); 2046 } 2047 } 2048 if (!bDefault) { 2049 return; 2050 } 2051 if (pOldIDArray) { 2052 CPDF_Object* pID2 = pOldIDArray->GetElement(1); 2053 if ((m_dwFlags & FPDFCREATE_INCREMENTAL) && m_pEncryptDict && pID2) { 2054 m_pIDArray->Add(pID2->Clone()); 2055 return; 2056 } 2057 FX_LPDWORD pBuffer = FX_Alloc(FX_DWORD, 4); 2058 PDF_GenerateFileID((FX_DWORD)(FX_UINTPTR)this, m_dwLastObjNum, pBuffer); 2059 CFX_ByteStringC bsBuffer((FX_LPCBYTE)pBuffer, 4 * sizeof(FX_DWORD)); 2060 m_pIDArray->Add(CPDF_String::Create(bsBuffer, TRUE), m_pDocument); 2061 FX_Free(pBuffer); 2062 return; 2063 } 2064 m_pIDArray->Add(m_pIDArray->GetElement(0)->Clone()); 2065 if (m_pEncryptDict && !pOldIDArray && m_pParser && bNewId) { 2066 if (m_pEncryptDict->GetString(FX_BSTRC("Filter")) == FX_BSTRC("Standard")) { 2067 CPDF_StandardSecurityHandler handler; 2068 CFX_ByteString user_pass = m_pParser->GetPassword(); 2069 FX_DWORD flag = PDF_ENCRYPT_CONTENT; 2070 handler.OnCreate(m_pEncryptDict, m_pIDArray, (FX_LPCBYTE)user_pass, user_pass.GetLength(), flag); 2071 if (m_pCryptoHandler && m_bNewCrypto) { 2072 delete m_pCryptoHandler; 2073 } 2074 m_pCryptoHandler = FX_NEW CPDF_StandardCryptoHandler; 2075 m_pCryptoHandler->Init(m_pEncryptDict, &handler); 2076 m_bNewCrypto = TRUE; 2077 m_bSecurityChanged = TRUE; 2078 } 2079 } 2080 } 2081 FX_INT32 CPDF_Creator::Continue(IFX_Pause *pPause) 2082 { 2083 if (m_iStage < 0) { 2084 return m_iStage; 2085 } 2086 FX_INT32 iRet; 2087 while (m_iStage < 100) { 2088 if (m_iStage < 20) { 2089 iRet = WriteDoc_Stage1(pPause); 2090 } else if (m_iStage < 30) { 2091 iRet = WriteDoc_Stage2(pPause); 2092 } else if (m_iStage < 90) { 2093 iRet = WriteDoc_Stage3(pPause); 2094 } else { 2095 iRet = WriteDoc_Stage4(pPause); 2096 } 2097 if (iRet < m_iStage) { 2098 break; 2099 } 2100 } 2101 if (iRet < 1 || m_iStage == 100) { 2102 m_iStage = -1; 2103 Clear(); 2104 return iRet > 99 ? 0 : (iRet < 1 ? -1 : iRet); 2105 } 2106 return m_iStage; 2107 } 2108 FX_BOOL CPDF_Creator::SetFileVersion(FX_INT32 fileVersion ) 2109 { 2110 if (fileVersion < 10 || fileVersion > 17) { 2111 return FALSE; 2112 } 2113 m_FileVersion = fileVersion; 2114 return TRUE; 2115 } 2116 void CPDF_Creator::ResetStandardSecurity() 2117 { 2118 if ((m_bStandardSecurity || m_bNewCrypto) && m_pCryptoHandler) { 2119 delete m_pCryptoHandler; 2120 m_pCryptoHandler = NULL; 2121 } 2122 m_bNewCrypto = FALSE; 2123 if (!m_bStandardSecurity) { 2124 return; 2125 } 2126 if (m_pEncryptDict) { 2127 m_pEncryptDict->Release(); 2128 m_pEncryptDict = NULL; 2129 } 2130 m_bStandardSecurity = FALSE; 2131 } 2132