Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(176)

Side by Side Diff: core/src/fpdfapi/fpdf_edit/fpdf_edit_create.cpp

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

Powered by Google App Engine
This is Rietveld 408576698