FX Bool considered harmful, part 3
[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 uint8_t* src_buf, FX_DWORD src_size, uint8_t*& 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         uint8_t 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(uint8_t, zcount * 4 + (pos - zcount));
43     int state = 0;
44     uint32_t res = 0;
45     pos = dest_size = 0;
46     while (pos < src_size) {
47         uint8_t ch = src_buf[pos++];
48         if (ch == '\n' || ch == '\r' || ch == ' ' || ch == '\t') {
49             continue;
50         }
51         if (ch == 'z') {
52             FXSYS_memset(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++] = (uint8_t)(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++] = (uint8_t)(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 uint8_t* src_buf, FX_DWORD src_size, uint8_t*& 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( uint8_t, i / 2 + 1);
93     dest_size = 0;
94     bool bFirstDigit = true;
95     for (i = 0; i < src_size; i ++) {
96         uint8_t 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 uint8_t* src_buf, FX_DWORD src_size, uint8_t*& 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( uint8_t, 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_memset(dest_buf + dest_count + copy_len, '\0', delta);
163             }
164             FXSYS_memcpy(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_memset(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(const uint8_t* src_buf, FX_DWORD src_size, int width, int height,
186         const CPDF_Dictionary* pParams)
187 {
188     int K = 0;
189     bool EndOfLine = false;
190     bool ByteAlign = false;
191     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 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(const uint8_t* 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     int Colors = 0, BitsPerComponent = 0, Columns = 0;
236     if (pParams) {
237         predictor = ((CPDF_Dictionary*)pParams)->GetInteger(FX_BSTRC("Predictor"));
238         Colors = pParams->GetInteger(FX_BSTRC("Colors"), 1);
239         BitsPerComponent = pParams->GetInteger(FX_BSTRC("BitsPerComponent"), 8);
240         Columns = pParams->GetInteger(FX_BSTRC("Columns"), 1);
241         if (!CheckFlateDecodeParams(Colors, BitsPerComponent, Columns)) {
242             return NULL;
243         }
244     }
245     return CPDF_ModuleMgr::Get()->GetFlateModule()->CreateDecoder(src_buf, src_size, width, height,
246             nComps, bpc, predictor, Colors, BitsPerComponent, Columns);
247 }
248 FX_DWORD FPDFAPI_FlateOrLZWDecode(bool bLZW, const uint8_t* src_buf, FX_DWORD src_size, CPDF_Dictionary* pParams,
249                                   FX_DWORD estimated_size, uint8_t*& dest_buf, FX_DWORD& dest_size)
250 {
251     int predictor = 0;
252     bool bEarlyChange = true;
253     int Colors = 0, BitsPerComponent = 0, Columns = 0;
254     if (pParams) {
255         predictor = ((CPDF_Dictionary*)pParams)->GetInteger(FX_BSTRC("Predictor"));
256         bEarlyChange = ((CPDF_Dictionary*)pParams)->GetInteger(FX_BSTRC("EarlyChange"), 1);
257         Colors = pParams->GetInteger(FX_BSTRC("Colors"), 1);
258         BitsPerComponent = pParams->GetInteger(FX_BSTRC("BitsPerComponent"), 8);
259         Columns = pParams->GetInteger(FX_BSTRC("Columns"), 1);
260         if (!CheckFlateDecodeParams(Colors, BitsPerComponent, Columns)) {
261             return (FX_DWORD) - 1;
262         }
263     }
264     return CPDF_ModuleMgr::Get()->GetFlateModule()->FlateOrLZWDecode(bLZW, src_buf, src_size,
265             bEarlyChange, predictor, Colors, BitsPerComponent, Columns, estimated_size,
266             dest_buf, dest_size);
267 }
268 bool PDF_DataDecode(const uint8_t* src_buf, FX_DWORD src_size, const CPDF_Dictionary* pDict,
269                        uint8_t*& dest_buf, FX_DWORD& dest_size, CFX_ByteString& ImageEncoding,
270                        CPDF_Dictionary*& pImageParms, FX_DWORD last_estimated_size, bool bImageAcc)
271
272 {
273     CPDF_Object* pDecoder = pDict ? pDict->GetElementValue(FX_BSTRC("Filter")) : NULL;
274     if (pDecoder == NULL || (pDecoder->GetType() != PDFOBJ_ARRAY && pDecoder->GetType() != PDFOBJ_NAME)) {
275         return false;
276     }
277     CPDF_Object* pParams = pDict ? pDict->GetElementValue(FX_BSTRC("DecodeParms")) : NULL;
278     CFX_ByteStringArray DecoderList;
279     CFX_PtrArray ParamList;
280     if (pDecoder->GetType() == PDFOBJ_ARRAY) {
281         if (pParams && pParams->GetType() != PDFOBJ_ARRAY) {
282             pParams = NULL;
283         }
284         CPDF_Array* pDecoders = (CPDF_Array*)pDecoder;
285         for (FX_DWORD i = 0; i < pDecoders->GetCount(); i ++) {
286             CFX_ByteStringC str = pDecoders->GetConstString(i);
287             DecoderList.Add(str);
288             if (pParams) {
289                 ParamList.Add(((CPDF_Array*)pParams)->GetDict(i));
290             } else {
291                 ParamList.Add(NULL);
292             }
293         }
294     } else {
295         DecoderList.Add(pDecoder->GetConstString());
296         ParamList.Add(pParams ? pParams->GetDict() : NULL);
297     }
298     uint8_t* last_buf = (uint8_t*)src_buf;
299     FX_DWORD last_size = src_size;
300     for (int i = 0; i < DecoderList.GetSize(); i ++) {
301         int estimated_size = i == DecoderList.GetSize() - 1 ? last_estimated_size : 0;
302         CFX_ByteString decoder = DecoderList[i];
303         CPDF_Dictionary* pParam = (CPDF_Dictionary*)ParamList[i];
304         uint8_t* new_buf = NULL;
305         FX_DWORD new_size = (FX_DWORD) - 1;
306         int offset = -1;
307         if (decoder == FX_BSTRC("FlateDecode") || decoder == FX_BSTRC("Fl")) {
308             if (bImageAcc && i == DecoderList.GetSize() - 1) {
309                 ImageEncoding = FX_BSTRC("FlateDecode");
310                 dest_buf = (uint8_t*)last_buf;
311                 dest_size = last_size;
312                 pImageParms = pParam;
313                 return true;
314             }
315             offset = FPDFAPI_FlateOrLZWDecode(false, last_buf, last_size, pParam, estimated_size, new_buf, new_size);
316         } else if (decoder == FX_BSTRC("LZWDecode") || decoder == FX_BSTRC("LZW")) {
317             offset = FPDFAPI_FlateOrLZWDecode(true, last_buf, last_size, pParam, estimated_size, new_buf, new_size);
318         } else if (decoder == FX_BSTRC("ASCII85Decode") || decoder == FX_BSTRC("A85")) {
319             offset = _A85Decode(last_buf, last_size, new_buf, new_size);
320         } else if (decoder == FX_BSTRC("ASCIIHexDecode") || decoder == FX_BSTRC("AHx")) {
321             offset = _HexDecode(last_buf, last_size, new_buf, new_size);
322         } else if (decoder == FX_BSTRC("RunLengthDecode") || decoder == FX_BSTRC("RL")) {
323             if (bImageAcc && i == DecoderList.GetSize() - 1) {
324                 ImageEncoding = FX_BSTRC("RunLengthDecode");
325                 dest_buf = (uint8_t*)last_buf;
326                 dest_size = last_size;
327                 pImageParms = pParam;
328                 return true;
329             }
330             offset = RunLengthDecode(last_buf, last_size, new_buf, new_size);
331         } else {
332             if (decoder == FX_BSTRC("DCT")) {
333                 decoder = "DCTDecode";
334             } else if (decoder == FX_BSTRC("CCF")) {
335                 decoder = "CCITTFaxDecode";
336             } else if (decoder == FX_BSTRC("Crypt")) {
337                 continue;
338             }
339             ImageEncoding = decoder;
340             pImageParms = pParam;
341             dest_buf = (uint8_t*)last_buf;
342             dest_size = last_size;
343             return true;
344         }
345         if (last_buf != src_buf) {
346             FX_Free(last_buf);
347         }
348         if (offset == -1) {
349             return false;
350         }
351         last_buf = new_buf;
352         last_size = new_size;
353     }
354     ImageEncoding = "";
355     pImageParms = NULL;
356     dest_buf = last_buf;
357     dest_size = last_size;
358     return true;
359 }
360 extern const FX_WORD PDFDocEncoding[256] = {
361     0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009,
362     0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013,
363     0x0014, 0x0015, 0x0016, 0x0017, 0x02d8, 0x02c7, 0x02c6, 0x02d9, 0x02dd, 0x02db,
364     0x02da, 0x02dc, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
365     0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031,
366     0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b,
367     0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045,
368     0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
369     0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
370     0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063,
371     0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d,
372     0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
373     0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x0000, 0x2022, 0x2020,
374     0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044, 0x2039, 0x203a, 0x2212, 0x2030,
375     0x201e, 0x201c, 0x201d, 0x2018, 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141,
376     0x0152, 0x0160, 0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 0x0000,
377     0x20ac, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9,
378     0x00aa, 0x00ab, 0x00ac, 0x0000, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3,
379     0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd,
380     0x00be, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
381     0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1,
382     0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db,
383     0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5,
384     0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
385     0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9,
386     0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
387 };
388 CFX_WideString PDF_DecodeText(const uint8_t* src_data, FX_DWORD src_len, CFX_CharMap* pCharMap)
389 {
390     CFX_WideString result;
391     if (src_len >= 2 && ((src_data[0] == 0xfe && src_data[1] == 0xff) || (src_data[0] == 0xff && src_data[1] == 0xfe))) {
392         bool bBE = src_data[0] == 0xfe;
393         FX_DWORD max_chars = (src_len - 2) / 2;
394         if (!max_chars) {
395             return result;
396         }
397         if (src_data[0] == 0xff) {
398             bBE = !src_data[2];
399         }
400         FX_WCHAR* dest_buf = result.GetBuffer(max_chars);
401         const uint8_t* uni_str = src_data + 2;
402         int dest_pos = 0;
403         for (FX_DWORD i = 0; i < max_chars * 2; i += 2) {
404             FX_WORD unicode = bBE ? (uni_str[i] << 8 | uni_str[i + 1]) : (uni_str[i + 1] << 8 | uni_str[i]);
405             if (unicode == 0x1b) {
406                 i += 2;
407                 while (i < max_chars * 2) {
408                     FX_WORD unicode = bBE ? (uni_str[i] << 8 | uni_str[i + 1]) : (uni_str[i + 1] << 8 | uni_str[i]);
409                     i += 2;
410                     if (unicode == 0x1b) {
411                         break;
412                     }
413                 }
414             } else {
415                 dest_buf[dest_pos++] = unicode;
416             }
417         }
418         result.ReleaseBuffer(dest_pos);
419     } else if (pCharMap == NULL) {
420         FX_WCHAR* dest_buf = result.GetBuffer(src_len);
421         for (FX_DWORD i = 0; i < src_len; i ++) {
422             dest_buf[i] = PDFDocEncoding[src_data[i]];
423         }
424         result.ReleaseBuffer(src_len);
425     } else {
426         return (*pCharMap->m_GetWideString)(pCharMap, CFX_ByteString((const FX_CHAR*)src_data, src_len));
427     }
428     return result;
429 }
430 CFX_ByteString PDF_EncodeText(const FX_WCHAR* pString, int len, CFX_CharMap* pCharMap)
431 {
432     if (len == -1) {
433         len = FXSYS_wcslen(pString);
434     }
435     CFX_ByteString result;
436     if (pCharMap == NULL) {
437         FX_CHAR* dest_buf1 = result.GetBuffer(len);
438         int i;
439         for (i = 0; i < len; i ++) {
440             int code;
441             for (code = 0; code < 256; code ++)
442                 if (PDFDocEncoding[code] == pString[i]) {
443                     break;
444                 }
445             if (code == 256) {
446                 break;
447             }
448             dest_buf1[i] = code;
449         }
450         result.ReleaseBuffer(i);
451         if (i == len) {
452             return result;
453         }
454     }
455
456     if(len > INT_MAX/2-1)
457     {
458         result.ReleaseBuffer(0);
459         return result;
460     }
461
462     int encLen = len * 2 + 2;
463
464     uint8_t* dest_buf2 = (uint8_t*)result.GetBuffer(encLen);
465     dest_buf2[0] = 0xfe;
466     dest_buf2[1] = 0xff;
467     dest_buf2 += 2;
468     for (int i = 0; i < len; i ++) {
469         *dest_buf2++ = pString[i] >> 8;
470         *dest_buf2++ = (uint8_t)pString[i];
471     }
472     result.ReleaseBuffer(encLen);
473     return result;
474 }
475 CFX_ByteString PDF_EncodeString(const CFX_ByteString& src, bool bHex)
476 {
477     CFX_ByteTextBuf result;
478     int srclen = src.GetLength();
479     if (bHex) {
480         result.AppendChar('<');
481         for (int i = 0; i < srclen; i ++) {
482             result.AppendChar("0123456789ABCDEF"[src[i] / 16]);
483             result.AppendChar("0123456789ABCDEF"[src[i] % 16]);
484         }
485         result.AppendChar('>');
486         return result.GetByteString();
487     }
488     result.AppendChar('(');
489     for (int i = 0; i < srclen; i ++) {
490         uint8_t ch = src[i];
491         if (ch == ')' || ch == '\\' || ch == '(') {
492             result.AppendChar('\\');
493         } else if (ch == 0x0a) {
494             result << FX_BSTRC("\\n");
495             continue;
496         } else if (ch == 0x0d) {
497             result << FX_BSTRC("\\r");
498             continue;
499         }
500         result.AppendChar(ch);
501     }
502     result.AppendChar(')');
503     return result.GetByteString();
504 }
505 void FlateEncode(const uint8_t* src_buf, FX_DWORD src_size, uint8_t*& dest_buf, FX_DWORD& dest_size)
506 {
507     CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
508     if (pEncoders) {
509         pEncoders->GetFlateModule()->Encode(src_buf, src_size, dest_buf, dest_size);
510     }
511 }
512 void FlateEncode(const uint8_t* src_buf, FX_DWORD src_size, int predictor, int Colors, int BitsPerComponent, int Columns,
513                  uint8_t*& dest_buf, FX_DWORD& dest_size)
514 {
515     CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
516     if (pEncoders) {
517         pEncoders->GetFlateModule()->Encode(src_buf, src_size, predictor, Colors, BitsPerComponent, Columns, dest_buf, dest_size);
518     }
519 }
520 FX_DWORD FlateDecode(const uint8_t* src_buf, FX_DWORD src_size, uint8_t*& dest_buf, FX_DWORD& dest_size)
521 {
522     CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
523     if (pEncoders) {
524         return pEncoders->GetFlateModule()->FlateOrLZWDecode(false, src_buf, src_size, false, 0, 0, 0, 0, 0, dest_buf, dest_size);
525     }
526     return 0;
527 }