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