Merge to XFA:Remove FX_STRSIZE casts, use safe conversions
[pdfium.git] / core / src / fpdfapi / fpdf_parser / fpdf_parser_decode.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "../../../include/fpdfapi/fpdf_parser.h"
8 #include "../../../include/fpdfapi/fpdf_module.h"
9 #include "../../../include/fxcodec/fx_codec.h"
10 #include <limits.h>
11 #define _STREAM_MAX_SIZE_               20 * 1024 * 1024
12 FX_DWORD _A85Decode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
13 {
14     dest_size = 0;
15     dest_buf = NULL;
16     if (src_size == 0) {
17         return 0;
18     }
19     FX_DWORD zcount = 0;
20     FX_DWORD pos = 0;
21     while (pos < src_size) {
22         FX_BYTE ch = src_buf[pos];
23         if (ch < '!' && ch != '\n' && ch != '\r' && ch != ' ' && ch != '\t') {
24             break;
25         }
26         if (ch == 'z') {
27             zcount ++;
28         } else if (ch > 'u') {
29             break;
30         }
31         pos ++;
32     }
33     if (pos == 0) {
34         return 0;
35     }
36     if (zcount > UINT_MAX / 4) {
37         return (FX_DWORD) - 1;
38     }
39     if (zcount * 4 > UINT_MAX - (pos - zcount)) {
40         return (FX_DWORD) - 1;
41     }
42     dest_buf = FX_Alloc(FX_BYTE, zcount * 4 + (pos - zcount));
43     if (dest_buf == NULL) {
44         return (FX_DWORD) - 1;
45     }
46     int state = 0;
47     FX_UINT32 res = 0;
48     pos = dest_size = 0;
49     while (pos < src_size) {
50         FX_BYTE ch = src_buf[pos++];
51         if (ch == '\n' || ch == '\r' || ch == ' ' || ch == '\t') {
52             continue;
53         }
54         if (ch == 'z') {
55             FXSYS_memset32(dest_buf + dest_size, 0, 4);
56             state = 0;
57             res = 0;
58             dest_size += 4;
59         } else {
60             if (ch < '!' || ch > 'u') {
61                 break;
62             }
63             res = res * 85 + ch - 33;
64             state ++;
65             if (state == 5) {
66                 for (int i = 0; i < 4; i ++) {
67                     dest_buf[dest_size++] = (FX_BYTE)(res >> (3 - i) * 8);
68                 }
69                 state = 0;
70                 res = 0;
71             }
72         }
73     }
74     if (state) {
75         int i;
76         for (i = state; i < 5; i ++) {
77             res = res * 85 + 84;
78         }
79         for (i = 0; i < state - 1; i ++) {
80             dest_buf[dest_size++] = (FX_BYTE)(res >> (3 - i) * 8);
81         }
82     }
83     if (pos < src_size && src_buf[pos] == '>') {
84         pos ++;
85     }
86     return pos;
87 }
88 FX_DWORD _HexDecode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
89 {
90     FX_DWORD i;
91     for (i = 0; i < src_size; i ++)
92         if (src_buf[i] == '>') {
93             break;
94         }
95     dest_buf = FX_Alloc( FX_BYTE, i / 2 + 1);
96     dest_size = 0;
97     FX_BOOL bFirstDigit = TRUE;
98     for (i = 0; i < src_size; i ++) {
99         FX_BYTE ch = src_buf[i];
100         if (ch == ' ' || ch == '\n' || ch == '\t' || ch == '\r') {
101             continue;
102         }
103         int digit;
104         if (ch <= '9' && ch >= '0') {
105             digit = ch - '0';
106         } else if (ch <= 'f' && ch >= 'a') {
107             digit = ch - 'a' + 10;
108         } else if (ch <= 'F' && ch >= 'A') {
109             digit = ch - 'A' + 10;
110         } else if (ch == '>') {
111             i ++;
112             break;
113         } else {
114             continue;
115         }
116         if (bFirstDigit) {
117             dest_buf[dest_size] = digit * 16;
118         } else {
119             dest_buf[dest_size ++] += digit;
120         }
121         bFirstDigit = !bFirstDigit;
122     }
123     if (!bFirstDigit) {
124         dest_size ++;
125     }
126     return i;
127 }
128 FX_DWORD RunLengthDecode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
129 {
130     FX_DWORD i = 0;
131     FX_DWORD old;
132     dest_size = 0;
133     while (i < src_size) {
134         if (src_buf[i] < 128) {
135             old = dest_size;
136             dest_size += src_buf[i] + 1;
137             if (dest_size < old) {
138                 return (FX_DWORD) - 1;
139             }
140             i += src_buf[i] + 2;
141         } else if (src_buf[i] > 128) {
142             old = dest_size;
143             dest_size += 257 - src_buf[i];
144             if (dest_size < old) {
145                 return (FX_DWORD) - 1;
146             }
147             i += 2;
148         } else {
149             break;
150         }
151     }
152     if (dest_size >= _STREAM_MAX_SIZE_) {
153         return -1;
154     }
155     dest_buf = FX_Alloc( FX_BYTE, dest_size);
156     if (!dest_buf) {
157         return -1;
158     }
159     i = 0;
160     int dest_count = 0;
161     while (i < src_size) {
162         if (src_buf[i] < 128) {
163             FX_DWORD copy_len = src_buf[i] + 1;
164             FX_DWORD buf_left = src_size - i - 1;
165             if (buf_left < copy_len) {
166                 FX_DWORD delta = copy_len - buf_left;
167                 copy_len = buf_left;
168                 FXSYS_memset8(dest_buf + dest_count + copy_len, '\0', delta);
169             }
170             FXSYS_memcpy32(dest_buf + dest_count, src_buf + i + 1, copy_len);
171             dest_count += src_buf[i] + 1;
172             i += src_buf[i] + 2;
173         } else if (src_buf[i] > 128) {
174             int fill = 0;
175             if (i < src_size - 1) {
176                 fill = src_buf[i + 1];
177             }
178             FXSYS_memset8(dest_buf + dest_count, fill, 257 - src_buf[i]);
179             dest_count += 257 - src_buf[i];
180             i += 2;
181         } else {
182             break;
183         }
184     }
185     FX_DWORD ret = i + 1;
186     if (ret > src_size) {
187         ret = src_size;
188     }
189     return ret;
190 }
191 ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height,
192         const CPDF_Dictionary* pParams)
193 {
194     int K = 0;
195     FX_BOOL EndOfLine = FALSE;
196     FX_BOOL ByteAlign = FALSE;
197     FX_BOOL BlackIs1 = FALSE;
198     int Columns = 1728;
199     int Rows = 0;
200     if (pParams) {
201         K = pParams->GetInteger(FX_BSTRC("K"));
202         EndOfLine = pParams->GetInteger(FX_BSTRC("EndOfLine"));
203         ByteAlign = pParams->GetInteger(FX_BSTRC("EncodedByteAlign"));
204         BlackIs1 = pParams->GetInteger(FX_BSTRC("BlackIs1"));
205         Columns = pParams->GetInteger(FX_BSTRC("Columns"), 1728);
206         Rows = pParams->GetInteger(FX_BSTRC("Rows"));
207         if (Rows > USHRT_MAX) {
208             Rows = 0;
209         }
210         if (Columns <= 0 || Rows < 0 || Columns > USHRT_MAX || Rows > USHRT_MAX) {
211             return NULL;
212         }
213     }
214     return CPDF_ModuleMgr::Get()->GetFaxModule()->CreateDecoder(src_buf, src_size, width, height,
215             K, EndOfLine, ByteAlign, BlackIs1, Columns, Rows);
216 }
217 static FX_BOOL CheckFlateDecodeParams(int Colors, int BitsPerComponent, int Columns)
218 {
219     if (Columns < 0) {
220         return FALSE;
221     }
222     int check = Columns;
223     if (Colors < 0 || (check > 0 && Colors > INT_MAX / check)) {
224         return FALSE;
225     }
226     check *= Colors;
227     if (BitsPerComponent < 0 ||
228             (check > 0 && BitsPerComponent > INT_MAX / check)) {
229         return FALSE;
230     }
231     check *= BitsPerComponent;
232     if (check > INT_MAX - 7) {
233         return FALSE;
234     }
235     return TRUE;
236 }
237 ICodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height,
238         int nComps, int bpc, const CPDF_Dictionary* pParams)
239 {
240     int predictor = 0;
241     FX_BOOL bEarlyChange = TRUE;
242     int Colors = 0, BitsPerComponent = 0, Columns = 0;
243     if (pParams) {
244         predictor = ((CPDF_Dictionary*)pParams)->GetInteger(FX_BSTRC("Predictor"));
245         bEarlyChange = ((CPDF_Dictionary*)pParams)->GetInteger(FX_BSTRC("EarlyChange"), 1);
246         Colors = pParams->GetInteger(FX_BSTRC("Colors"), 1);
247         BitsPerComponent = pParams->GetInteger(FX_BSTRC("BitsPerComponent"), 8);
248         Columns = pParams->GetInteger(FX_BSTRC("Columns"), 1);
249         if (!CheckFlateDecodeParams(Colors, BitsPerComponent, Columns)) {
250             return NULL;
251         }
252     }
253     return CPDF_ModuleMgr::Get()->GetFlateModule()->CreateDecoder(src_buf, src_size, width, height,
254             nComps, bpc, predictor, Colors, BitsPerComponent, Columns);
255 }
256 FX_DWORD FPDFAPI_FlateOrLZWDecode(FX_BOOL bLZW, const FX_BYTE* src_buf, FX_DWORD src_size, CPDF_Dictionary* pParams,
257                                   FX_DWORD estimated_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
258 {
259     int predictor = 0;
260     FX_BOOL bEarlyChange = TRUE;
261     int Colors = 0, BitsPerComponent = 0, Columns = 0;
262     if (pParams) {
263         predictor = ((CPDF_Dictionary*)pParams)->GetInteger(FX_BSTRC("Predictor"));
264         bEarlyChange = ((CPDF_Dictionary*)pParams)->GetInteger(FX_BSTRC("EarlyChange"), 1);
265         Colors = pParams->GetInteger(FX_BSTRC("Colors"), 1);
266         BitsPerComponent = pParams->GetInteger(FX_BSTRC("BitsPerComponent"), 8);
267         Columns = pParams->GetInteger(FX_BSTRC("Columns"), 1);
268         if (!CheckFlateDecodeParams(Colors, BitsPerComponent, Columns)) {
269             return (FX_DWORD) - 1;
270         }
271     }
272     return CPDF_ModuleMgr::Get()->GetFlateModule()->FlateOrLZWDecode(bLZW, src_buf, src_size,
273             bEarlyChange, predictor, Colors, BitsPerComponent, Columns, estimated_size,
274             dest_buf, dest_size);
275 }
276 FX_BOOL PDF_DataDecode(FX_LPCBYTE src_buf, FX_DWORD src_size, const CPDF_Dictionary* pDict,
277                        FX_LPBYTE& dest_buf, FX_DWORD& dest_size, CFX_ByteString& ImageEncoding,
278                        CPDF_Dictionary*& pImageParms, FX_DWORD last_estimated_size, FX_BOOL bImageAcc)
279
280 {
281     CPDF_Object* pDecoder = pDict ? pDict->GetElementValue(FX_BSTRC("Filter")) : NULL;
282     if (pDecoder == NULL || (pDecoder->GetType() != PDFOBJ_ARRAY && pDecoder->GetType() != PDFOBJ_NAME)) {
283         return FALSE;
284     }
285     CPDF_Object* pParams = pDict ? pDict->GetElementValue(FX_BSTRC("DecodeParms")) : NULL;
286     CFX_ByteStringArray DecoderList;
287     CFX_PtrArray ParamList;
288     if (pDecoder->GetType() == PDFOBJ_ARRAY) {
289         if (pParams && pParams->GetType() != PDFOBJ_ARRAY) {
290             pParams = NULL;
291         }
292         CPDF_Array* pDecoders = (CPDF_Array*)pDecoder;
293         for (FX_DWORD i = 0; i < pDecoders->GetCount(); i ++) {
294             CFX_ByteStringC str = pDecoders->GetConstString(i);
295             DecoderList.Add(str);
296             if (pParams) {
297                 ParamList.Add(((CPDF_Array*)pParams)->GetDict(i));
298             } else {
299                 ParamList.Add(NULL);
300             }
301         }
302     } else {
303         DecoderList.Add(pDecoder->GetConstString());
304         ParamList.Add(pParams ? pParams->GetDict() : NULL);
305     }
306     FX_LPBYTE last_buf = (FX_LPBYTE)src_buf;
307     FX_DWORD last_size = src_size;
308     for (int i = 0; i < DecoderList.GetSize(); i ++) {
309         int estimated_size = i == DecoderList.GetSize() - 1 ? last_estimated_size : 0;
310         CFX_ByteString decoder = DecoderList[i];
311         CPDF_Dictionary* pParam = (CPDF_Dictionary*)ParamList[i];
312         FX_LPBYTE new_buf = NULL;
313         FX_DWORD new_size = (FX_DWORD) - 1;
314         int offset = -1;
315         if (decoder == FX_BSTRC("FlateDecode") || decoder == FX_BSTRC("Fl")) {
316             if (bImageAcc && i == DecoderList.GetSize() - 1) {
317                 ImageEncoding = FX_BSTRC("FlateDecode");
318                 dest_buf = (FX_LPBYTE)last_buf;
319                 dest_size = last_size;
320                 pImageParms = pParam;
321                 return TRUE;
322             } else {
323                 offset = FPDFAPI_FlateOrLZWDecode(FALSE, last_buf, last_size, pParam, estimated_size, new_buf, new_size);
324             }
325         } else if (decoder == FX_BSTRC("LZWDecode") || decoder == FX_BSTRC("LZW")) {
326             offset = FPDFAPI_FlateOrLZWDecode(TRUE, last_buf, last_size, pParam, estimated_size, new_buf, new_size);
327         } else if (decoder == FX_BSTRC("ASCII85Decode") || decoder == FX_BSTRC("A85")) {
328             offset = _A85Decode(last_buf, last_size, new_buf, new_size);
329         } else if (decoder == FX_BSTRC("ASCIIHexDecode") || decoder == FX_BSTRC("AHx")) {
330             offset = _HexDecode(last_buf, last_size, new_buf, new_size);
331         } else if (decoder == FX_BSTRC("RunLengthDecode") || decoder == FX_BSTRC("RL")) {
332             if (bImageAcc && i == DecoderList.GetSize() - 1) {
333                 ImageEncoding = FX_BSTRC("RunLengthDecode");
334                 dest_buf = (FX_LPBYTE)last_buf;
335                 dest_size = last_size;
336                 pImageParms = pParam;
337                 return TRUE;
338             }
339             offset = RunLengthDecode(last_buf, last_size, new_buf, new_size);
340         } else {
341             if (decoder == FX_BSTRC("DCT")) {
342                 decoder = "DCTDecode";
343             } else if (decoder == FX_BSTRC("CCF")) {
344                 decoder = "CCITTFaxDecode";
345             } else if (decoder == FX_BSTRC("Crypt")) {
346                 continue;
347             }
348             ImageEncoding = decoder;
349             pImageParms = pParam;
350             dest_buf = (FX_LPBYTE)last_buf;
351             dest_size = last_size;
352             return TRUE;
353         }
354         if (last_buf != src_buf) {
355             FX_Free(last_buf);
356         }
357         if (offset == -1) {
358             return FALSE;
359         }
360         last_buf = new_buf;
361         last_size = new_size;
362     }
363     ImageEncoding = "";
364     pImageParms = NULL;
365     dest_buf = last_buf;
366     dest_size = last_size;
367     return TRUE;
368 }
369 extern const FX_WORD PDFDocEncoding[256] = {
370     0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009,
371     0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013,
372     0x0014, 0x0015, 0x0016, 0x0017, 0x02d8, 0x02c7, 0x02c6, 0x02d9, 0x02dd, 0x02db,
373     0x02da, 0x02dc, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
374     0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031,
375     0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b,
376     0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045,
377     0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
378     0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
379     0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063,
380     0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d,
381     0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
382     0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x0000, 0x2022, 0x2020,
383     0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044, 0x2039, 0x203a, 0x2212, 0x2030,
384     0x201e, 0x201c, 0x201d, 0x2018, 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141,
385     0x0152, 0x0160, 0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 0x0000,
386     0x20ac, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9,
387     0x00aa, 0x00ab, 0x00ac, 0x0000, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3,
388     0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd,
389     0x00be, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
390     0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1,
391     0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db,
392     0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5,
393     0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
394     0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9,
395     0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
396 };
397 CFX_WideString PDF_DecodeText(FX_LPCBYTE src_data, FX_DWORD src_len, CFX_CharMap* pCharMap)
398 {
399     CFX_WideString result;
400     if (src_len >= 2 && ((src_data[0] == 0xfe && src_data[1] == 0xff) || (src_data[0] == 0xff && src_data[1] == 0xfe))) {
401         FX_BOOL bBE = src_data[0] == 0xfe;
402         FX_DWORD max_chars = (src_len - 2) / 2;
403         if (!max_chars) {
404             return result;
405         }
406         if (src_data[0] == 0xff) {
407             bBE = !src_data[2];
408         }
409         FX_LPWSTR dest_buf = result.GetBuffer(max_chars);
410         FX_LPCBYTE uni_str = src_data + 2;
411         int dest_pos = 0;
412         for (FX_DWORD i = 0; i < max_chars * 2; i += 2) {
413             FX_WORD unicode = bBE ? (uni_str[i] << 8 | uni_str[i + 1]) : (uni_str[i + 1] << 8 | uni_str[i]);
414             if (unicode == 0x1b) {
415                 i += 2;
416                 while (i < max_chars * 2) {
417                     FX_WORD unicode = bBE ? (uni_str[i] << 8 | uni_str[i + 1]) : (uni_str[i + 1] << 8 | uni_str[i]);
418                     i += 2;
419                     if (unicode == 0x1b) {
420                         break;
421                     }
422                 }
423             } else {
424                 dest_buf[dest_pos++] = unicode;
425             }
426         }
427         result.ReleaseBuffer(dest_pos);
428     } else if (pCharMap == NULL) {
429         FX_LPWSTR dest_buf = result.GetBuffer(src_len);
430         for (FX_DWORD i = 0; i < src_len; i ++) {
431             dest_buf[i] = PDFDocEncoding[src_data[i]];
432         }
433         result.ReleaseBuffer(src_len);
434     } else {
435         return (*pCharMap->m_GetWideString)(pCharMap, CFX_ByteString((FX_LPCSTR)src_data, src_len));
436     }
437     return result;
438 }
439 CFX_ByteString PDF_EncodeText(FX_LPCWSTR pString, int len, CFX_CharMap* pCharMap)
440 {
441     if (len == -1) {
442         len = FXSYS_wcslen(pString);
443     }
444     CFX_ByteString result;
445     if (pCharMap == NULL) {
446         FX_LPSTR dest_buf1 = result.GetBuffer(len);
447         int i;
448         for (i = 0; i < len; i ++) {
449             int code;
450             for (code = 0; code < 256; code ++)
451                 if (PDFDocEncoding[code] == pString[i]) {
452                     break;
453                 }
454             if (code == 256) {
455                 break;
456             }
457             dest_buf1[i] = code;
458         }
459         result.ReleaseBuffer(i);
460         if (i == len) {
461             return result;
462         }
463     }
464
465     if(len > INT_MAX/2-1)
466     {
467         result.ReleaseBuffer(0);
468         return result;
469     }
470
471     int encLen = len * 2 + 2;
472
473     FX_LPBYTE dest_buf2 = (FX_LPBYTE)result.GetBuffer(encLen);
474     dest_buf2[0] = 0xfe;
475     dest_buf2[1] = 0xff;
476     dest_buf2 += 2;
477     for (int i = 0; i < len; i ++) {
478         *dest_buf2++ = pString[i] >> 8;
479         *dest_buf2++ = (FX_BYTE)pString[i];
480     }
481     result.ReleaseBuffer(encLen);
482     return result;
483 }
484 CFX_ByteString PDF_EncodeString(const CFX_ByteString& src, FX_BOOL bHex)
485 {
486     CFX_ByteTextBuf result;
487     int srclen = src.GetLength();
488     if (bHex) {
489         result.AppendChar('<');
490         for (int i = 0; i < srclen; i ++) {
491             result.AppendChar("0123456789ABCDEF"[src[i] / 16]);
492             result.AppendChar("0123456789ABCDEF"[src[i] % 16]);
493         }
494         result.AppendChar('>');
495         return result.GetByteString();
496     }
497     result.AppendChar('(');
498     for (int i = 0; i < srclen; i ++) {
499         FX_BYTE ch = src[i];
500         if (ch == ')' || ch == '\\' || ch == '(') {
501             result.AppendChar('\\');
502         } else if (ch == 0x0a) {
503             result << FX_BSTRC("\\n");
504             continue;
505         } else if (ch == 0x0d) {
506             result << FX_BSTRC("\\r");
507             continue;
508         }
509         result.AppendChar(ch);
510     }
511     result.AppendChar(')');
512     return result.GetByteString();
513 }
514 void FlateEncode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
515 {
516     CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
517     if (pEncoders) {
518         pEncoders->GetFlateModule()->Encode(src_buf, src_size, dest_buf, dest_size);
519     }
520 }
521 void FlateEncode(FX_LPCBYTE src_buf, FX_DWORD src_size, int predictor, int Colors, int BitsPerComponent, int Columns,
522                  FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
523 {
524     CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
525     if (pEncoders) {
526         pEncoders->GetFlateModule()->Encode(src_buf, src_size, predictor, Colors, BitsPerComponent, Columns, dest_buf, dest_size);
527     }
528 }
529 FX_DWORD FlateDecode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
530 {
531     CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
532     if (pEncoders) {
533         return pEncoders->GetFlateModule()->FlateOrLZWDecode(FALSE, src_buf, src_size, FALSE, 0, 0, 0, 0, 0, dest_buf, dest_size);
534     }
535     return 0;
536 }