Home | History | Annotate | Download | only in fpdf_parser
      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     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(FX_BOOL bLZW, const FX_BYTE* src_buf, FX_DWORD src_size, CPDF_Dictionary* pParams,
    249                                   FX_DWORD estimated_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
    250 {
    251     int predictor = 0;
    252     FX_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 FX_BOOL PDF_DataDecode(FX_LPCBYTE src_buf, FX_DWORD src_size, const CPDF_Dictionary* pDict,
    269                        FX_LPBYTE& dest_buf, FX_DWORD& dest_size, CFX_ByteString& ImageEncoding,
    270                        CPDF_Dictionary*& pImageParms, FX_DWORD last_estimated_size, FX_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     FX_LPBYTE last_buf = (FX_LPBYTE)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         FX_LPBYTE 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 = (FX_LPBYTE)last_buf;
    311                 dest_size = last_size;
    312                 pImageParms = pParam;
    313                 return TRUE;
    314             } else {
    315                 offset = FPDFAPI_FlateOrLZWDecode(FALSE, last_buf, last_size, pParam, estimated_size, new_buf, new_size);
    316             }
    317         } else if (decoder == FX_BSTRC("LZWDecode") || decoder == FX_BSTRC("LZW")) {
    318             offset = FPDFAPI_FlateOrLZWDecode(TRUE, last_buf, last_size, pParam, estimated_size, new_buf, new_size);
    319         } else if (decoder == FX_BSTRC("ASCII85Decode") || decoder == FX_BSTRC("A85")) {
    320             offset = _A85Decode(last_buf, last_size, new_buf, new_size);
    321         } else if (decoder == FX_BSTRC("ASCIIHexDecode") || decoder == FX_BSTRC("AHx")) {
    322             offset = _HexDecode(last_buf, last_size, new_buf, new_size);
    323         } else if (decoder == FX_BSTRC("RunLengthDecode") || decoder == FX_BSTRC("RL")) {
    324             if (bImageAcc && i == DecoderList.GetSize() - 1) {
    325                 ImageEncoding = FX_BSTRC("RunLengthDecode");
    326                 dest_buf = (FX_LPBYTE)last_buf;
    327                 dest_size = last_size;
    328                 pImageParms = pParam;
    329                 return TRUE;
    330             }
    331             offset = RunLengthDecode(last_buf, last_size, new_buf, new_size);
    332         } else {
    333             if (decoder == FX_BSTRC("DCT")) {
    334                 decoder = "DCTDecode";
    335             } else if (decoder == FX_BSTRC("CCF")) {
    336                 decoder = "CCITTFaxDecode";
    337             } else if (decoder == FX_BSTRC("Crypt")) {
    338                 continue;
    339             }
    340             ImageEncoding = decoder;
    341             pImageParms = pParam;
    342             dest_buf = (FX_LPBYTE)last_buf;
    343             dest_size = last_size;
    344             return TRUE;
    345         }
    346         if (last_buf != src_buf) {
    347             FX_Free(last_buf);
    348         }
    349         if (offset == -1) {
    350             return FALSE;
    351         }
    352         last_buf = new_buf;
    353         last_size = new_size;
    354     }
    355     ImageEncoding = "";
    356     pImageParms = NULL;
    357     dest_buf = last_buf;
    358     dest_size = last_size;
    359     return TRUE;
    360 }
    361 extern const FX_WORD PDFDocEncoding[256] = {
    362     0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009,
    363     0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013,
    364     0x0014, 0x0015, 0x0016, 0x0017, 0x02d8, 0x02c7, 0x02c6, 0x02d9, 0x02dd, 0x02db,
    365     0x02da, 0x02dc, 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
    366     0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, 0x0031,
    367     0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b,
    368     0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045,
    369     0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
    370     0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059,
    371     0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0060, 0x0061, 0x0062, 0x0063,
    372     0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d,
    373     0x006e, 0x006f, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
    374     0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x0000, 0x2022, 0x2020,
    375     0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044, 0x2039, 0x203a, 0x2212, 0x2030,
    376     0x201e, 0x201c, 0x201d, 0x2018, 0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141,
    377     0x0152, 0x0160, 0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 0x0000,
    378     0x20ac, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9,
    379     0x00aa, 0x00ab, 0x00ac, 0x0000, 0x00ae, 0x00af, 0x00b0, 0x00b1, 0x00b2, 0x00b3,
    380     0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd,
    381     0x00be, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
    382     0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1,
    383     0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db,
    384     0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5,
    385     0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
    386     0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9,
    387     0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
    388 };
    389 CFX_WideString PDF_DecodeText(FX_LPCBYTE src_data, FX_DWORD src_len, CFX_CharMap* pCharMap)
    390 {
    391     CFX_WideString result;
    392     if (src_len >= 2 && ((src_data[0] == 0xfe && src_data[1] == 0xff) || (src_data[0] == 0xff && src_data[1] == 0xfe))) {
    393         FX_BOOL bBE = src_data[0] == 0xfe;
    394         FX_DWORD max_chars = (src_len - 2) / 2;
    395         if (!max_chars) {
    396             return result;
    397         }
    398         if (src_data[0] == 0xff) {
    399             bBE = !src_data[2];
    400         }
    401         FX_LPWSTR dest_buf = result.GetBuffer(max_chars);
    402         FX_LPCBYTE uni_str = src_data + 2;
    403         int dest_pos = 0;
    404         for (FX_DWORD i = 0; i < max_chars * 2; i += 2) {
    405             FX_WORD unicode = bBE ? (uni_str[i] << 8 | uni_str[i + 1]) : (uni_str[i + 1] << 8 | uni_str[i]);
    406             if (unicode == 0x1b) {
    407                 i += 2;
    408                 while (i < max_chars * 2) {
    409                     FX_WORD unicode = bBE ? (uni_str[i] << 8 | uni_str[i + 1]) : (uni_str[i + 1] << 8 | uni_str[i]);
    410                     i += 2;
    411                     if (unicode == 0x1b) {
    412                         break;
    413                     }
    414                 }
    415             } else {
    416                 dest_buf[dest_pos++] = unicode;
    417             }
    418         }
    419         result.ReleaseBuffer(dest_pos);
    420     } else if (pCharMap == NULL) {
    421         FX_LPWSTR dest_buf = result.GetBuffer(src_len);
    422         for (FX_DWORD i = 0; i < src_len; i ++) {
    423             dest_buf[i] = PDFDocEncoding[src_data[i]];
    424         }
    425         result.ReleaseBuffer(src_len);
    426     } else {
    427         return (*pCharMap->m_GetWideString)(pCharMap, CFX_ByteString((FX_LPCSTR)src_data, src_len));
    428     }
    429     return result;
    430 }
    431 CFX_ByteString PDF_EncodeText(FX_LPCWSTR pString, int len, CFX_CharMap* pCharMap)
    432 {
    433     if (len == -1) {
    434         len = FXSYS_wcslen(pString);
    435     }
    436     CFX_ByteString result;
    437     if (pCharMap == NULL) {
    438         FX_LPSTR dest_buf1 = result.GetBuffer(len);
    439         int i;
    440         for (i = 0; i < len; i ++) {
    441             int code;
    442             for (code = 0; code < 256; code ++)
    443                 if (PDFDocEncoding[code] == pString[i]) {
    444                     break;
    445                 }
    446             if (code == 256) {
    447                 break;
    448             }
    449             dest_buf1[i] = code;
    450         }
    451         result.ReleaseBuffer(i);
    452         if (i == len) {
    453             return result;
    454         }
    455     }
    456 
    457     if(len > INT_MAX/2-1)
    458     {
    459         result.ReleaseBuffer(0);
    460         return result;
    461     }
    462 
    463     int encLen = len * 2 + 2;
    464 
    465     FX_LPBYTE dest_buf2 = (FX_LPBYTE)result.GetBuffer(encLen);
    466     dest_buf2[0] = 0xfe;
    467     dest_buf2[1] = 0xff;
    468     dest_buf2 += 2;
    469     for (int i = 0; i < len; i ++) {
    470         *dest_buf2++ = pString[i] >> 8;
    471         *dest_buf2++ = (FX_BYTE)pString[i];
    472     }
    473     result.ReleaseBuffer(encLen);
    474     return result;
    475 }
    476 CFX_ByteString PDF_EncodeString(const CFX_ByteString& src, FX_BOOL bHex)
    477 {
    478     CFX_ByteTextBuf result;
    479     int srclen = src.GetLength();
    480     if (bHex) {
    481         result.AppendChar('<');
    482         for (int i = 0; i < srclen; i ++) {
    483             result.AppendChar("0123456789ABCDEF"[src[i] / 16]);
    484             result.AppendChar("0123456789ABCDEF"[src[i] % 16]);
    485         }
    486         result.AppendChar('>');
    487         return result.GetByteString();
    488     }
    489     result.AppendChar('(');
    490     for (int i = 0; i < srclen; i ++) {
    491         FX_BYTE ch = src[i];
    492         if (ch == ')' || ch == '\\' || ch == '(') {
    493             result.AppendChar('\\');
    494         } else if (ch == 0x0a) {
    495             result << FX_BSTRC("\\n");
    496             continue;
    497         } else if (ch == 0x0d) {
    498             result << FX_BSTRC("\\r");
    499             continue;
    500         }
    501         result.AppendChar(ch);
    502     }
    503     result.AppendChar(')');
    504     return result.GetByteString();
    505 }
    506 void FlateEncode(const FX_BYTE* src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
    507 {
    508     CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
    509     if (pEncoders) {
    510         pEncoders->GetFlateModule()->Encode(src_buf, src_size, dest_buf, dest_size);
    511     }
    512 }
    513 void FlateEncode(FX_LPCBYTE src_buf, FX_DWORD src_size, int predictor, int Colors, int BitsPerComponent, int Columns,
    514                  FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
    515 {
    516     CCodec_ModuleMgr* pEncoders = CPDF_ModuleMgr::Get()->GetCodecModule();
    517     if (pEncoders) {
    518         pEncoders->GetFlateModule()->Encode(src_buf, src_size, predictor, Colors, BitsPerComponent, Columns, dest_buf, dest_size);
    519     }
    520 }
    521 FX_DWORD FlateDecode(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         return pEncoders->GetFlateModule()->FlateOrLZWDecode(FALSE, src_buf, src_size, FALSE, 0, 0, 0, 0, 0, dest_buf, dest_size);
    526     }
    527     return 0;
    528 }
    529