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