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