85ba130b774daaa86f8371f195e4955413037a1f
[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,
13                     FX_DWORD src_size,
14                     uint8_t*& dest_buf,
15                     FX_DWORD& dest_size) {
16   dest_size = 0;
17   dest_buf = NULL;
18   if (src_size == 0) {
19     return 0;
20   }
21   FX_DWORD zcount = 0;
22   FX_DWORD pos = 0;
23   while (pos < src_size) {
24     uint8_t ch = src_buf[pos];
25     if (ch < '!' && ch != '\n' && ch != '\r' && ch != ' ' && ch != '\t') {
26       break;
27     }
28     if (ch == 'z') {
29       zcount++;
30     } else if (ch > 'u') {
31       break;
32     }
33     pos++;
34   }
35   if (pos == 0) {
36     return 0;
37   }
38   if (zcount > UINT_MAX / 4) {
39     return (FX_DWORD)-1;
40   }
41   if (zcount * 4 > UINT_MAX - (pos - zcount)) {
42     return (FX_DWORD)-1;
43   }
44   dest_buf = FX_Alloc(uint8_t, zcount * 4 + (pos - zcount));
45   int state = 0;
46   uint32_t res = 0;
47   pos = dest_size = 0;
48   while (pos < src_size) {
49     uint8_t ch = src_buf[pos++];
50     if (ch == '\n' || ch == '\r' || ch == ' ' || ch == '\t') {
51       continue;
52     }
53     if (ch == 'z') {
54       FXSYS_memset(dest_buf + dest_size, 0, 4);
55       state = 0;
56       res = 0;
57       dest_size += 4;
58     } else {
59       if (ch < '!' || ch > 'u') {
60         break;
61       }
62       res = res * 85 + ch - 33;
63       state++;
64       if (state == 5) {
65         for (int i = 0; i < 4; i++) {
66           dest_buf[dest_size++] = (uint8_t)(res >> (3 - i) * 8);
67         }
68         state = 0;
69         res = 0;
70       }
71     }
72   }
73   if (state) {
74     int i;
75     for (i = state; i < 5; i++) {
76       res = res * 85 + 84;
77     }
78     for (i = 0; i < state - 1; i++) {
79       dest_buf[dest_size++] = (uint8_t)(res >> (3 - i) * 8);
80     }
81   }
82   if (pos < src_size && src_buf[pos] == '>') {
83     pos++;
84   }
85   return pos;
86 }
87 FX_DWORD _HexDecode(const uint8_t* src_buf,
88                     FX_DWORD src_size,
89                     uint8_t*& dest_buf,
90                     FX_DWORD& 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(uint8_t, i / 2 + 1);
97   dest_size = 0;
98   FX_BOOL bFirstDigit = TRUE;
99   for (i = 0; i < src_size; i++) {
100     uint8_t 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 }
129 FX_DWORD RunLengthDecode(const uint8_t* src_buf,
130                          FX_DWORD src_size,
131                          uint8_t*& dest_buf,
132                          FX_DWORD& 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(uint8_t, dest_size);
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_memset(dest_buf + dest_count + copy_len, '\0', delta);
169       }
170       FXSYS_memcpy(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_memset(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(
192     const uint8_t* src_buf,
193     FX_DWORD src_size,
194     int width,
195     int height,
196     const CPDF_Dictionary* pParams) {
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(
218       src_buf, src_size, width, height, K, EndOfLine, ByteAlign, BlackIs1,
219       Columns, Rows);
220 }
221 static FX_BOOL CheckFlateDecodeParams(int Colors,
222                                       int BitsPerComponent,
223                                       int Columns) {
224   if (Columns < 0) {
225     return FALSE;
226   }
227   int check = Columns;
228   if (Colors < 0 || (check > 0 && Colors > INT_MAX / check)) {
229     return FALSE;
230   }
231   check *= Colors;
232   if (BitsPerComponent < 0 ||
233       (check > 0 && BitsPerComponent > INT_MAX / check)) {
234     return FALSE;
235   }
236   check *= BitsPerComponent;
237   if (check > INT_MAX - 7) {
238     return FALSE;
239   }
240   return TRUE;
241 }
242 ICodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder(
243     const uint8_t* src_buf,
244     FX_DWORD src_size,
245     int width,
246     int height,
247     int nComps,
248     int bpc,
249     const CPDF_Dictionary* pParams) {
250   int predictor = 0;
251   int Colors = 0, BitsPerComponent = 0, Columns = 0;
252   if (pParams) {
253     predictor = ((CPDF_Dictionary*)pParams)->GetInteger(FX_BSTRC("Predictor"));
254     Colors = pParams->GetInteger(FX_BSTRC("Colors"), 1);
255     BitsPerComponent = pParams->GetInteger(FX_BSTRC("BitsPerComponent"), 8);
256     Columns = pParams->GetInteger(FX_BSTRC("Columns"), 1);
257     if (!CheckFlateDecodeParams(Colors, BitsPerComponent, Columns)) {
258       return NULL;
259     }
260   }
261   return CPDF_ModuleMgr::Get()->GetFlateModule()->CreateDecoder(
262       src_buf, src_size, width, height, nComps, bpc, predictor, Colors,
263       BitsPerComponent, Columns);
264 }
265 FX_DWORD FPDFAPI_FlateOrLZWDecode(FX_BOOL bLZW,
266                                   const uint8_t* src_buf,
267                                   FX_DWORD src_size,
268                                   CPDF_Dictionary* pParams,
269                                   FX_DWORD estimated_size,
270                                   uint8_t*& dest_buf,
271                                   FX_DWORD& dest_size) {
272   int predictor = 0;
273   FX_BOOL bEarlyChange = TRUE;
274   int Colors = 0, BitsPerComponent = 0, Columns = 0;
275   if (pParams) {
276     predictor = ((CPDF_Dictionary*)pParams)->GetInteger(FX_BSTRC("Predictor"));
277     bEarlyChange =
278         ((CPDF_Dictionary*)pParams)->GetInteger(FX_BSTRC("EarlyChange"), 1);
279     Colors = pParams->GetInteger(FX_BSTRC("Colors"), 1);
280     BitsPerComponent = pParams->GetInteger(FX_BSTRC("BitsPerComponent"), 8);
281     Columns = pParams->GetInteger(FX_BSTRC("Columns"), 1);
282     if (!CheckFlateDecodeParams(Colors, BitsPerComponent, Columns)) {
283       return (FX_DWORD)-1;
284     }
285   }
286   return CPDF_ModuleMgr::Get()->GetFlateModule()->FlateOrLZWDecode(
287       bLZW, src_buf, src_size, bEarlyChange, predictor, Colors,
288       BitsPerComponent, Columns, estimated_size, dest_buf, dest_size);
289 }
290 FX_BOOL PDF_DataDecode(const uint8_t* src_buf,
291                        FX_DWORD src_size,
292                        const CPDF_Dictionary* pDict,
293                        uint8_t*& dest_buf,
294                        FX_DWORD& dest_size,
295                        CFX_ByteString& ImageEncoding,
296                        CPDF_Dictionary*& pImageParms,
297                        FX_DWORD last_estimated_size,
298                        FX_BOOL bImageAcc)
299
300 {
301   CPDF_Object* pDecoder =
302       pDict ? pDict->GetElementValue(FX_BSTRC("Filter")) : NULL;
303   if (pDecoder == NULL || (pDecoder->GetType() != PDFOBJ_ARRAY &&
304                            pDecoder->GetType() != PDFOBJ_NAME)) {
305     return FALSE;
306   }
307   CPDF_Object* pParams =
308       pDict ? pDict->GetElementValue(FX_BSTRC("DecodeParms")) : NULL;
309   CFX_ByteStringArray DecoderList;
310   CFX_PtrArray ParamList;
311   if (pDecoder->GetType() == PDFOBJ_ARRAY) {
312     if (pParams && pParams->GetType() != PDFOBJ_ARRAY) {
313       pParams = NULL;
314     }
315     CPDF_Array* pDecoders = (CPDF_Array*)pDecoder;
316     for (FX_DWORD i = 0; i < pDecoders->GetCount(); i++) {
317       CFX_ByteStringC str = pDecoders->GetConstString(i);
318       DecoderList.Add(str);
319       if (pParams) {
320         ParamList.Add(((CPDF_Array*)pParams)->GetDict(i));
321       } else {
322         ParamList.Add(NULL);
323       }
324     }
325   } else {
326     DecoderList.Add(pDecoder->GetConstString());
327     ParamList.Add(pParams ? pParams->GetDict() : NULL);
328   }
329   uint8_t* last_buf = (uint8_t*)src_buf;
330   FX_DWORD last_size = src_size;
331   for (int i = 0; i < DecoderList.GetSize(); i++) {
332     int estimated_size =
333         i == DecoderList.GetSize() - 1 ? last_estimated_size : 0;
334     CFX_ByteString decoder = DecoderList[i];
335     CPDF_Dictionary* pParam = (CPDF_Dictionary*)ParamList[i];
336     uint8_t* new_buf = NULL;
337     FX_DWORD new_size = (FX_DWORD)-1;
338     int offset = -1;
339     if (decoder == FX_BSTRC("FlateDecode") || decoder == FX_BSTRC("Fl")) {
340       if (bImageAcc && i == DecoderList.GetSize() - 1) {
341         ImageEncoding = FX_BSTRC("FlateDecode");
342         dest_buf = (uint8_t*)last_buf;
343         dest_size = last_size;
344         pImageParms = pParam;
345         return TRUE;
346       }
347       offset = FPDFAPI_FlateOrLZWDecode(FALSE, last_buf, last_size, pParam,
348                                         estimated_size, new_buf, new_size);
349     } else if (decoder == FX_BSTRC("LZWDecode") || decoder == FX_BSTRC("LZW")) {
350       offset = FPDFAPI_FlateOrLZWDecode(TRUE, last_buf, last_size, pParam,
351                                         estimated_size, new_buf, new_size);
352     } else if (decoder == FX_BSTRC("ASCII85Decode") ||
353                decoder == FX_BSTRC("A85")) {
354       offset = _A85Decode(last_buf, last_size, new_buf, new_size);
355     } else if (decoder == FX_BSTRC("ASCIIHexDecode") ||
356                decoder == FX_BSTRC("AHx")) {
357       offset = _HexDecode(last_buf, last_size, new_buf, new_size);
358     } else if (decoder == FX_BSTRC("RunLengthDecode") ||
359                decoder == FX_BSTRC("RL")) {
360       if (bImageAcc && i == DecoderList.GetSize() - 1) {
361         ImageEncoding = FX_BSTRC("RunLengthDecode");
362         dest_buf = (uint8_t*)last_buf;
363         dest_size = last_size;
364         pImageParms = pParam;
365         return TRUE;
366       }
367       offset = RunLengthDecode(last_buf, last_size, new_buf, new_size);
368     } else {
369       if (decoder == FX_BSTRC("DCT")) {
370         decoder = "DCTDecode";
371       } else if (decoder == FX_BSTRC("CCF")) {
372         decoder = "CCITTFaxDecode";
373       } else if (decoder == FX_BSTRC("Crypt")) {
374         continue;
375       }
376       ImageEncoding = decoder;
377       pImageParms = pParam;
378       dest_buf = (uint8_t*)last_buf;
379       dest_size = last_size;
380       return TRUE;
381     }
382     if (last_buf != src_buf) {
383       FX_Free(last_buf);
384     }
385     if (offset == -1) {
386       return FALSE;
387     }
388     last_buf = new_buf;
389     last_size = new_size;
390   }
391   ImageEncoding = "";
392   pImageParms = NULL;
393   dest_buf = last_buf;
394   dest_size = last_size;
395   return TRUE;
396 }
397 extern const FX_WORD PDFDocEncoding[256] = {
398     0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008,
399     0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011,
400     0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x02d8, 0x02c7, 0x02c6,
401     0x02d9, 0x02dd, 0x02db, 0x02da, 0x02dc, 0x0020, 0x0021, 0x0022, 0x0023,
402     0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c,
403     0x002d, 0x002e, 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035,
404     0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e,
405     0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
406     0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050,
407     0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
408     0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062,
409     0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b,
410     0x006c, 0x006d, 0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074,
411     0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d,
412     0x007e, 0x0000, 0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192,
413     0x2044, 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018,
414     0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, 0x0152, 0x0160, 0x0178,
415     0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 0x0000, 0x20ac, 0x00a1,
416     0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa,
417     0x00ab, 0x00ac, 0x0000, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3,
418     0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc,
419     0x00bd, 0x00be, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5,
420     0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce,
421     0x00cf, 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
422     0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0,
423     0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9,
424     0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2,
425     0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb,
426     0x00fc, 0x00fd, 0x00fe, 0x00ff};
427 CFX_WideString PDF_DecodeText(const uint8_t* src_data,
428                               FX_DWORD src_len,
429                               CFX_CharMap* pCharMap) {
430   CFX_WideString result;
431   if (src_len >= 2 && ((src_data[0] == 0xfe && src_data[1] == 0xff) ||
432                        (src_data[0] == 0xff && src_data[1] == 0xfe))) {
433     FX_BOOL bBE = src_data[0] == 0xfe;
434     FX_DWORD max_chars = (src_len - 2) / 2;
435     if (!max_chars) {
436       return result;
437     }
438     if (src_data[0] == 0xff) {
439       bBE = !src_data[2];
440     }
441     FX_WCHAR* dest_buf = result.GetBuffer(max_chars);
442     const uint8_t* uni_str = src_data + 2;
443     int dest_pos = 0;
444     for (FX_DWORD i = 0; i < max_chars * 2; i += 2) {
445       FX_WORD unicode = bBE ? (uni_str[i] << 8 | uni_str[i + 1])
446                             : (uni_str[i + 1] << 8 | uni_str[i]);
447       if (unicode == 0x1b) {
448         i += 2;
449         while (i < max_chars * 2) {
450           FX_WORD unicode = bBE ? (uni_str[i] << 8 | uni_str[i + 1])
451                                 : (uni_str[i + 1] << 8 | uni_str[i]);
452           i += 2;
453           if (unicode == 0x1b) {
454             break;
455           }
456         }
457       } else {
458         dest_buf[dest_pos++] = unicode;
459       }
460     }
461     result.ReleaseBuffer(dest_pos);
462   } else if (pCharMap == NULL) {
463     FX_WCHAR* dest_buf = result.GetBuffer(src_len);
464     for (FX_DWORD i = 0; i < src_len; i++) {
465       dest_buf[i] = PDFDocEncoding[src_data[i]];
466     }
467     result.ReleaseBuffer(src_len);
468   } else {
469     return (*pCharMap->m_GetWideString)(
470         pCharMap, CFX_ByteString((const FX_CHAR*)src_data, src_len));
471   }
472   return result;
473 }
474 CFX_ByteString PDF_EncodeText(const FX_WCHAR* pString,
475                               int len,
476                               CFX_CharMap* pCharMap) {
477   if (len == -1) {
478     len = FXSYS_wcslen(pString);
479   }
480   CFX_ByteString result;
481   if (pCharMap == NULL) {
482     FX_CHAR* dest_buf1 = result.GetBuffer(len);
483     int i;
484     for (i = 0; i < len; i++) {
485       int code;
486       for (code = 0; code < 256; code++)
487         if (PDFDocEncoding[code] == pString[i]) {
488           break;
489         }
490       if (code == 256) {
491         break;
492       }
493       dest_buf1[i] = code;
494     }
495     result.ReleaseBuffer(i);
496     if (i == len) {
497       return result;
498     }
499   }
500
501   if (len > INT_MAX / 2 - 1) {
502     result.ReleaseBuffer(0);
503     return result;
504   }
505
506   int encLen = len * 2 + 2;
507
508   uint8_t* dest_buf2 = (uint8_t*)result.GetBuffer(encLen);
509   dest_buf2[0] = 0xfe;
510   dest_buf2[1] = 0xff;
511   dest_buf2 += 2;
512   for (int i = 0; i < len; i++) {
513     *dest_buf2++ = pString[i] >> 8;
514     *dest_buf2++ = (uint8_t)pString[i];
515   }
516   result.ReleaseBuffer(encLen);
517   return result;
518 }
519 CFX_ByteString PDF_EncodeString(const CFX_ByteString& src, FX_BOOL bHex) {
520   CFX_ByteTextBuf result;
521   int srclen = src.GetLength();
522   if (bHex) {
523     result.AppendChar('<');
524     for (int i = 0; i < srclen; i++) {
525       result.AppendChar("0123456789ABCDEF"[src[i] / 16]);
526       result.AppendChar("0123456789ABCDEF"[src[i] % 16]);
527     }
528     result.AppendChar('>');
529     return result.GetByteString();
530   }
531   result.AppendChar('(');
532   for (int i = 0; i < srclen; i++) {
533     uint8_t ch = src[i];
534     if (ch == ')' || ch == '\\' || ch == '(') {
535       result.AppendChar('\\');
536     } else if (ch == 0x0a) {
537       result << FX_BSTRC("\\n");
538       continue;
539     } else if (ch == 0x0d) {
540       result << FX_BSTRC("\\r");
541       continue;
542     }
543     result.AppendChar(ch);
544   }
545   result.AppendChar(')');
546   return result.GetByteString();
547 }
548 void FlateEncode(const uint8_t* src_buf,
549                  FX_DWORD src_size,
550                  uint8_t*& dest_buf,
551                  FX_DWORD& dest_size) {
552   CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
553   if (pEncoders) {
554     pEncoders->GetFlateModule()->Encode(src_buf, src_size, dest_buf, dest_size);
555   }
556 }
557 void FlateEncode(const uint8_t* src_buf,
558                  FX_DWORD src_size,
559                  int predictor,
560                  int Colors,
561                  int BitsPerComponent,
562                  int Columns,
563                  uint8_t*& dest_buf,
564                  FX_DWORD& dest_size) {
565   CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
566   if (pEncoders) {
567     pEncoders->GetFlateModule()->Encode(src_buf, src_size, predictor, Colors,
568                                         BitsPerComponent, Columns, dest_buf,
569                                         dest_size);
570   }
571 }
572 FX_DWORD FlateDecode(const uint8_t* src_buf,
573                      FX_DWORD src_size,
574                      uint8_t*& dest_buf,
575                      FX_DWORD& dest_size) {
576   CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
577   if (pEncoders) {
578     return pEncoders->GetFlateModule()->FlateOrLZWDecode(
579         FALSE, src_buf, src_size, FALSE, 0, 0, 0, 0, 0, dest_buf, dest_size);
580   }
581   return 0;
582 }