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 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 }
     88 FX_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 }
    129 FX_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 }
    193 ICodec_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 }
    219 static 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 }
    239 ICodec_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 }
    258 FX_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 }
    278 FX_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 }
    371 extern 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 };
    399 CFX_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 }
    441 CFX_WideString PDF_DecodeText(const CFX_ByteString& bstr, CFX_CharMap* pCharMap)
    442 {
    443     return PDF_DecodeText((FX_LPCBYTE)(FX_LPCSTR)bstr, bstr.GetLength(), pCharMap);
    444 }
    445 CFX_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 }
    481 CFX_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 }
    511 void 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 }
    518 void 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 }
    526 FX_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