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