Home | History | Annotate | Download | only in codec
      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 "../../fx_zlib.h"
      8 #include "../../../include/fxcodec/fx_codec.h"
      9 #include "codec_int.h"
     10 extern "C"
     11 {
     12     static void* my_alloc_func (void* opaque, unsigned int items, unsigned int size)
     13     {
     14         return FX_Alloc(FX_BYTE, items * size);
     15     }
     16     static void   my_free_func  (void* opaque, void* address)
     17     {
     18         FX_Free(address);
     19     }
     20     void* FPDFAPI_FlateInit(void* (*alloc_func)(void*, unsigned int, unsigned int),
     21                             void (*free_func)(void*, void*))
     22     {
     23         z_stream* p = (z_stream*)alloc_func(0, 1, sizeof(z_stream));
     24         if (p == NULL) {
     25             return NULL;
     26         }
     27         FXSYS_memset32(p, 0, sizeof(z_stream));
     28         p->zalloc = alloc_func;
     29         p->zfree = free_func;
     30         inflateInit(p);
     31         return p;
     32     }
     33     void FPDFAPI_FlateInput(void* context, const unsigned char* src_buf, unsigned int src_size)
     34     {
     35         ((z_stream*)context)->next_in = (unsigned char*)src_buf;
     36         ((z_stream*)context)->avail_in = src_size;
     37     }
     38     int FPDFAPI_FlateGetTotalOut(void* context)
     39     {
     40         return ((z_stream*)context)->total_out;
     41     }
     42     int FPDFAPI_FlateOutput(void* context, unsigned char* dest_buf, unsigned int dest_size)
     43     {
     44         ((z_stream*)context)->next_out = dest_buf;
     45         ((z_stream*)context)->avail_out = dest_size;
     46         unsigned int pre_pos = (unsigned int)FPDFAPI_FlateGetTotalOut(context);
     47         int ret = inflate((z_stream*)context, Z_SYNC_FLUSH);
     48         unsigned int post_pos = (unsigned int)FPDFAPI_FlateGetTotalOut(context);
     49         unsigned int written = post_pos - pre_pos;
     50         if (written < dest_size) {
     51             FXSYS_memset8(dest_buf + written, '\0', dest_size - written);
     52         }
     53         return ret;
     54     }
     55     int FPDFAPI_FlateGetTotalIn(void* context)
     56     {
     57         return ((z_stream*)context)->total_in;
     58     }
     59     int FPDFAPI_FlateGetAvailOut(void* context)
     60     {
     61         return ((z_stream*)context)->avail_out;
     62     }
     63     int FPDFAPI_FlateGetAvailIn(void* context)
     64     {
     65         return ((z_stream*)context)->avail_in;
     66     }
     67     void FPDFAPI_FlateEnd(void* context)
     68     {
     69         inflateEnd((z_stream*)context);
     70         ((z_stream*)context)->zfree(0, context);
     71     }
     72     void FPDFAPI_FlateCompress(unsigned char* dest_buf, unsigned long* dest_size, const unsigned char* src_buf, unsigned long src_size)
     73     {
     74         compress(dest_buf, dest_size, src_buf, src_size);
     75     }
     76 }
     77 class CLZWDecoder : public CFX_Object
     78 {
     79 public:
     80     FX_BOOL Decode(FX_LPBYTE output, FX_DWORD& outlen, const FX_BYTE* input, FX_DWORD& size, FX_BOOL bEarlyChange);
     81 private:
     82     FX_DWORD	m_InPos;
     83     FX_DWORD	m_OutPos;
     84     FX_LPBYTE	m_pOutput;
     85     const FX_BYTE*	m_pInput;
     86     FX_BOOL		m_Early;
     87     void		AddCode(FX_DWORD prefix_code, FX_BYTE append_char);
     88     FX_DWORD	m_CodeArray[5021];
     89     FX_DWORD	m_nCodes;
     90     FX_BYTE		m_DecodeStack[4000];
     91     FX_DWORD	m_StackLen;
     92     void		DecodeString(FX_DWORD code);
     93     int			m_CodeLen;
     94 };
     95 void CLZWDecoder::AddCode(FX_DWORD prefix_code, FX_BYTE append_char)
     96 {
     97     if (m_nCodes + m_Early == 4094) {
     98         return;
     99     }
    100     m_CodeArray[m_nCodes ++] = (prefix_code << 16) | append_char;
    101     if (m_nCodes + m_Early == 512 - 258) {
    102         m_CodeLen = 10;
    103     } else if (m_nCodes + m_Early == 1024 - 258) {
    104         m_CodeLen = 11;
    105     } else if (m_nCodes + m_Early == 2048 - 258) {
    106         m_CodeLen = 12;
    107     }
    108 }
    109 void CLZWDecoder::DecodeString(FX_DWORD code)
    110 {
    111     while (1) {
    112         int index = code - 258;
    113         if (index < 0 || index >= (int)m_nCodes) {
    114             break;
    115         }
    116         FX_DWORD data = m_CodeArray[index];
    117         if (m_StackLen >= sizeof(m_DecodeStack)) {
    118             return;
    119         }
    120         m_DecodeStack[m_StackLen++] = (FX_BYTE)data;
    121         code = data >> 16;
    122     }
    123     if (m_StackLen >= sizeof(m_DecodeStack)) {
    124         return;
    125     }
    126     m_DecodeStack[m_StackLen++] = (FX_BYTE)code;
    127 }
    128 int CLZWDecoder::Decode(FX_LPBYTE dest_buf, FX_DWORD& dest_size, const FX_BYTE* src_buf, FX_DWORD& src_size, FX_BOOL bEarlyChange)
    129 {
    130     m_CodeLen = 9;
    131     m_InPos = 0;
    132     m_OutPos = 0;
    133     m_pInput = src_buf;
    134     m_pOutput = dest_buf;
    135     m_Early = bEarlyChange ? 1 : 0;
    136     m_nCodes = 0;
    137     FX_DWORD old_code = (FX_DWORD) - 1;
    138     FX_BYTE last_char;
    139     while (1) {
    140         if (m_InPos + m_CodeLen > src_size * 8) {
    141             break;
    142         }
    143         int byte_pos = m_InPos / 8;
    144         int bit_pos = m_InPos % 8, bit_left = m_CodeLen;
    145         FX_DWORD code = 0;
    146         if (bit_pos) {
    147             bit_left -= 8 - bit_pos;
    148             code = (m_pInput[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left;
    149         }
    150         if (bit_left < 8) {
    151             code |= m_pInput[byte_pos] >> (8 - bit_left);
    152         } else {
    153             bit_left -= 8;
    154             code |= m_pInput[byte_pos++] << bit_left;
    155             if (bit_left) {
    156                 code |= m_pInput[byte_pos] >> (8 - bit_left);
    157             }
    158         }
    159         m_InPos += m_CodeLen;
    160         if (code < 256) {
    161             if (m_OutPos == dest_size) {
    162                 return -5;
    163             }
    164             if (m_pOutput) {
    165                 m_pOutput[m_OutPos] = (FX_BYTE)code;
    166             }
    167             m_OutPos ++;
    168             last_char = (FX_BYTE)code;
    169             if (old_code != (FX_DWORD) - 1) {
    170                 AddCode(old_code, last_char);
    171             }
    172             old_code = code;
    173         } else if (code == 256) {
    174             m_CodeLen = 9;
    175             m_nCodes = 0;
    176             old_code = (FX_DWORD) - 1;
    177         } else if (code == 257) {
    178             break;
    179         } else {
    180             if (old_code == (FX_DWORD) - 1) {
    181                 return 2;
    182             }
    183             m_StackLen = 0;
    184             if (code >= m_nCodes + 258) {
    185                 if (m_StackLen < sizeof(m_DecodeStack)) {
    186                     m_DecodeStack[m_StackLen++] = last_char;
    187                 }
    188                 DecodeString(old_code);
    189             } else {
    190                 DecodeString(code);
    191             }
    192             if (m_OutPos + m_StackLen > dest_size) {
    193                 return -5;
    194             }
    195             if (m_pOutput) {
    196                 for (FX_DWORD i = 0; i < m_StackLen; i ++) {
    197                     m_pOutput[m_OutPos + i] = m_DecodeStack[m_StackLen - i - 1];
    198                 }
    199             }
    200             m_OutPos += m_StackLen;
    201             last_char = m_DecodeStack[m_StackLen - 1];
    202             if (old_code < 256) {
    203                 AddCode(old_code, last_char);
    204             } else if (old_code - 258 >= m_nCodes) {
    205                 dest_size = m_OutPos;
    206                 src_size = (m_InPos + 7) / 8;
    207                 return 0;
    208             } else {
    209                 AddCode(old_code, last_char);
    210             }
    211             old_code = code;
    212         }
    213     }
    214     dest_size = m_OutPos;
    215     src_size = (m_InPos + 7) / 8;
    216     return 0;
    217 }
    218 static FX_BYTE PaethPredictor(int a, int b, int c)
    219 {
    220     int p = a + b - c;
    221     int pa = FXSYS_abs(p - a);
    222     int pb = FXSYS_abs(p - b);
    223     int pc = FXSYS_abs(p - c);
    224     if (pa <= pb && pa <= pc) {
    225         return (FX_BYTE)a;
    226     }
    227     if (pb <= pc) {
    228         return (FX_BYTE)b;
    229     }
    230     return (FX_BYTE)c;
    231 }
    232 static void PNG_PredictorEncode(FX_LPBYTE& data_buf, FX_DWORD& data_size, int predictor, int Colors, int BitsPerComponent, int Columns)
    233 {
    234     int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8;
    235     int row_size = (Colors * BitsPerComponent * Columns + 7) / 8;
    236     int row_count = (data_size + row_size - 1) / row_size;
    237     int last_row_size = data_size % row_size;
    238     FX_LPBYTE dest_buf = FX_Alloc( FX_BYTE, (row_size + 1) * row_count);
    239     if (dest_buf == NULL) {
    240         return;
    241     }
    242     int byte_cnt = 0;
    243     FX_LPBYTE pSrcData = data_buf;
    244     FX_LPBYTE pDestData = dest_buf;
    245     for (int row = 0; row < row_count; row++) {
    246         if (predictor == 10) {
    247             pDestData[0] = 0;
    248             int move_size = row_size;
    249             if (move_size * (row + 1) > (int)data_size) {
    250                 move_size = data_size - (move_size * row);
    251             }
    252             FXSYS_memmove32(pDestData + 1, pSrcData, move_size);
    253             pDestData += (move_size + 1);
    254             pSrcData += move_size;
    255             byte_cnt += move_size;
    256             continue;
    257         }
    258         for (int byte = 0; byte < row_size && byte_cnt < (int)data_size; byte++) {
    259             switch (predictor) {
    260                 case 11: {
    261                         pDestData[0] = 1;
    262                         FX_BYTE left = 0;
    263                         if (byte >= BytesPerPixel) {
    264                             left = pSrcData[byte - BytesPerPixel];
    265                         }
    266                         pDestData[byte + 1] = pSrcData[byte] - left;
    267                     }
    268                     break;
    269                 case 12: {
    270                         pDestData[0] = 2;
    271                         FX_BYTE up = 0;
    272                         if (row) {
    273                             up = pSrcData[byte - row_size];
    274                         }
    275                         pDestData[byte + 1] = pSrcData[byte] - up;
    276                     }
    277                     break;
    278                 case 13: {
    279                         pDestData[0] = 3;
    280                         FX_BYTE left = 0;
    281                         if (byte >= BytesPerPixel) {
    282                             left = pSrcData[byte - BytesPerPixel];
    283                         }
    284                         FX_BYTE up = 0;
    285                         if (row) {
    286                             up = pSrcData[byte - row_size];
    287                         }
    288                         pDestData[byte + 1] = pSrcData[byte] - (left + up) / 2;
    289                     }
    290                     break;
    291                 case 14: {
    292                         pDestData[0] = 4;
    293                         FX_BYTE left = 0;
    294                         if (byte >= BytesPerPixel) {
    295                             left = pSrcData[byte - BytesPerPixel];
    296                         }
    297                         FX_BYTE up = 0;
    298                         if (row) {
    299                             up = pSrcData[byte - row_size];
    300                         }
    301                         FX_BYTE upper_left = 0;
    302                         if (byte >= BytesPerPixel && row) {
    303                             upper_left = pSrcData[byte - row_size - BytesPerPixel];
    304                         }
    305                         pDestData[byte + 1] = pSrcData[byte] - PaethPredictor(left, up, upper_left);
    306                     }
    307                     break;
    308                 default: {
    309                         pDestData[byte + 1] = pSrcData[byte];
    310                     }
    311                     break;
    312             }
    313             byte_cnt++;
    314         }
    315         pDestData += (row_size + 1);
    316         pSrcData += row_size;
    317     }
    318     FX_Free(data_buf);
    319     data_buf = dest_buf;
    320     data_size = (row_size + 1) * row_count - (last_row_size > 0 ? (row_size - last_row_size) : 0);
    321 }
    322 static void PNG_PredictLine(FX_LPBYTE pDestData, FX_LPCBYTE pSrcData, FX_LPCBYTE pLastLine,
    323                             int bpc, int nColors, int nPixels)
    324 {
    325     int row_size = (nPixels * bpc * nColors + 7) / 8;
    326     int BytesPerPixel = (bpc * nColors + 7) / 8;
    327     FX_BYTE tag = pSrcData[0];
    328     if (tag == 0) {
    329         FXSYS_memmove32(pDestData, pSrcData + 1, row_size);
    330         return;
    331     }
    332     for (int byte = 0; byte < row_size; byte ++) {
    333         FX_BYTE raw_byte = pSrcData[byte + 1];
    334         switch (tag) {
    335             case 1:	{
    336                     FX_BYTE left = 0;
    337                     if (byte >= BytesPerPixel) {
    338                         left = pDestData[byte - BytesPerPixel];
    339                     }
    340                     pDestData[byte] = raw_byte + left;
    341                     break;
    342                 }
    343             case 2: {
    344                     FX_BYTE up = 0;
    345                     if (pLastLine) {
    346                         up = pLastLine[byte];
    347                     }
    348                     pDestData[byte] = raw_byte + up;
    349                     break;
    350                 }
    351             case 3: {
    352                     FX_BYTE left = 0;
    353                     if (byte >= BytesPerPixel) {
    354                         left = pDestData[byte - BytesPerPixel];
    355                     }
    356                     FX_BYTE up = 0;
    357                     if (pLastLine) {
    358                         up = pLastLine[byte];
    359                     }
    360                     pDestData[byte] = raw_byte + (up + left) / 2;
    361                     break;
    362                 }
    363             case 4: {
    364                     FX_BYTE left = 0;
    365                     if (byte >= BytesPerPixel) {
    366                         left = pDestData[byte - BytesPerPixel];
    367                     }
    368                     FX_BYTE up = 0;
    369                     if (pLastLine) {
    370                         up = pLastLine[byte];
    371                     }
    372                     FX_BYTE upper_left = 0;
    373                     if (byte >= BytesPerPixel && pLastLine) {
    374                         upper_left = pLastLine[byte - BytesPerPixel];
    375                     }
    376                     pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_left);
    377                     break;
    378                 }
    379             default:
    380                 pDestData[byte] = raw_byte;
    381                 break;
    382         }
    383     }
    384 }
    385 static void PNG_Predictor(FX_LPBYTE& data_buf, FX_DWORD& data_size,
    386                           int Colors, int BitsPerComponent, int Columns)
    387 {
    388     int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8;
    389     int row_size = (Colors * BitsPerComponent * Columns + 7) / 8;
    390     int row_count = (data_size + row_size) / (row_size + 1);
    391     int last_row_size = data_size % (row_size + 1);
    392     FX_LPBYTE dest_buf = FX_Alloc( FX_BYTE, row_size * row_count);
    393     if (dest_buf == NULL) {
    394         return;
    395     }
    396     int byte_cnt = 0;
    397     FX_LPBYTE pSrcData = data_buf;
    398     FX_LPBYTE pDestData = dest_buf;
    399     for (int row = 0; row < row_count; row ++) {
    400         FX_BYTE tag = pSrcData[0];
    401         if (tag == 0) {
    402             int move_size = row_size;
    403             if ((row + 1) * (move_size + 1) > (int)data_size) {
    404                 move_size = last_row_size - 1;
    405             }
    406             FXSYS_memmove32(pDestData, pSrcData + 1, move_size);
    407             pSrcData += move_size + 1;
    408             pDestData += move_size;
    409             byte_cnt += move_size + 1;
    410             continue;
    411         }
    412         for (int byte = 0; byte < row_size && byte_cnt < (int)data_size; byte ++) {
    413             FX_BYTE raw_byte = pSrcData[byte + 1];
    414             switch (tag) {
    415                 case 1:	{
    416                         FX_BYTE left = 0;
    417                         if (byte >= BytesPerPixel) {
    418                             left = pDestData[byte - BytesPerPixel];
    419                         }
    420                         pDestData[byte] = raw_byte + left;
    421                         break;
    422                     }
    423                 case 2: {
    424                         FX_BYTE up = 0;
    425                         if (row) {
    426                             up = pDestData[byte - row_size];
    427                         }
    428                         pDestData[byte] = raw_byte + up;
    429                         break;
    430                     }
    431                 case 3: {
    432                         FX_BYTE left = 0;
    433                         if (byte >= BytesPerPixel) {
    434                             left = pDestData[byte - BytesPerPixel];
    435                         }
    436                         FX_BYTE up = 0;
    437                         if (row) {
    438                             up = pDestData[byte - row_size];
    439                         }
    440                         pDestData[byte] = raw_byte + (up + left) / 2;
    441                         break;
    442                     }
    443                 case 4: {
    444                         FX_BYTE left = 0;
    445                         if (byte >= BytesPerPixel) {
    446                             left = pDestData[byte - BytesPerPixel];
    447                         }
    448                         FX_BYTE up = 0;
    449                         if (row) {
    450                             up = pDestData[byte - row_size];
    451                         }
    452                         FX_BYTE upper_left = 0;
    453                         if (byte >= BytesPerPixel && row) {
    454                             upper_left = pDestData[byte - row_size - BytesPerPixel];
    455                         }
    456                         pDestData[byte] = raw_byte + PaethPredictor(left, up, upper_left);
    457                         break;
    458                     }
    459                 default:
    460                     pDestData[byte] = raw_byte;
    461                     break;
    462             }
    463             byte_cnt++;
    464         }
    465         pSrcData += row_size + 1;
    466         pDestData += row_size;
    467         byte_cnt++;
    468     }
    469     FX_Free(data_buf);
    470     data_buf = dest_buf;
    471     data_size = row_size * row_count - (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0);
    472 }
    473 static void TIFF_PredictorEncodeLine(FX_LPBYTE dest_buf, int row_size, int BitsPerComponent, int Colors, int Columns)
    474 {
    475     int BytesPerPixel = BitsPerComponent * Colors / 8;
    476     if (BitsPerComponent < 8) {
    477         FX_BYTE mask = 0x01;
    478         if (BitsPerComponent == 2) {
    479             mask = 0x03;
    480         } else if (BitsPerComponent == 4) {
    481             mask = 0x0F;
    482         }
    483         int row_bits = Colors * BitsPerComponent * Columns;
    484         for (int i = row_bits - BitsPerComponent; i >= BitsPerComponent; i -= BitsPerComponent) {
    485             int col = i % 8;
    486             int index = i / 8;
    487             int col_pre = (col == 0) ? (8 - BitsPerComponent) : (col - BitsPerComponent);
    488             int index_pre = (col == 0) ? (index - 1) : index;
    489             FX_BYTE cur = (dest_buf[index] >> (8 - col - BitsPerComponent)) & mask;
    490             FX_BYTE left = (dest_buf[index_pre] >> (8 - col_pre - BitsPerComponent)) & mask;
    491             cur -= left;
    492             cur &= mask;
    493             cur <<= (8 - col - BitsPerComponent);
    494             dest_buf[index] &= ~(mask << ((8 - col - BitsPerComponent)));
    495             dest_buf[index] |= cur;
    496         }
    497     } else if (BitsPerComponent == 8) {
    498         for (int i = row_size - 1; i >= BytesPerPixel; i--) {
    499             dest_buf[i] -= dest_buf[i - BytesPerPixel];
    500         }
    501     } else {
    502         for (int i = row_size - BytesPerPixel; i >= BytesPerPixel; i -= BytesPerPixel) {
    503             FX_WORD pixel = (dest_buf[i] << 8) | dest_buf[i + 1];
    504             pixel -= (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1];
    505             dest_buf[i] = pixel >> 8;
    506             dest_buf[i + 1] = (FX_BYTE)pixel;
    507         }
    508     }
    509 }
    510 static void TIFF_PredictorEncode(FX_LPBYTE& data_buf, FX_DWORD& data_size,
    511                                  int Colors, int BitsPerComponent, int Columns)
    512 {
    513     int row_size = (Colors * BitsPerComponent * Columns + 7) / 8;
    514     int row_count = (data_size + row_size - 1) / row_size;
    515     int last_row_size = data_size % row_size;
    516     for (int row = 0; row < row_count; row++) {
    517         FX_LPBYTE scan_line = data_buf + row * row_size;
    518         if ((row + 1) * row_size > (int)data_size) {
    519             row_size = last_row_size;
    520         }
    521         TIFF_PredictorEncodeLine(scan_line, row_size, BitsPerComponent, Colors, Columns);
    522     }
    523 }
    524 static void TIFF_PredictLine(FX_LPBYTE dest_buf, int row_size, int BitsPerComponent, int Colors, int Columns)
    525 {
    526     if (BitsPerComponent == 1) {
    527         int row_bits = BitsPerComponent * Colors * Columns;
    528         for(int i = 1; i < row_bits; i ++) {
    529             int col = i % 8;
    530             int index = i / 8;
    531             int index_pre = (col == 0) ? (index - 1) : index;
    532             int col_pre = (col == 0) ? 8 : col;
    533             if( ((dest_buf[index] >> (7 - col)) & 1) ^ ((dest_buf[index_pre] >> (8 - col_pre)) & 1) ) {
    534                 dest_buf[index] |= 1 << (7 - col);
    535             } else {
    536                 dest_buf[index] &= ~(1 << (7 - col));
    537             }
    538         }
    539         return;
    540     }
    541     int BytesPerPixel = BitsPerComponent * Colors / 8;
    542     if (BitsPerComponent == 16) {
    543         for (int i = BytesPerPixel; i < row_size; i += 2) {
    544             FX_WORD pixel = (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1];
    545             pixel += (dest_buf[i] << 8) | dest_buf[i + 1];
    546             dest_buf[i] = pixel >> 8;
    547             dest_buf[i + 1] = (FX_BYTE)pixel;
    548         }
    549     } else {
    550         for (int i = BytesPerPixel; i < row_size; i ++) {
    551             dest_buf[i] += dest_buf[i - BytesPerPixel];
    552         }
    553     }
    554 }
    555 static void TIFF_Predictor(FX_LPBYTE& data_buf, FX_DWORD& data_size,
    556                            int Colors, int BitsPerComponent, int Columns)
    557 {
    558     int row_size = (Colors * BitsPerComponent * Columns + 7) / 8;
    559     int row_count = (data_size + row_size - 1) / row_size;
    560     int last_row_size = data_size % row_size;
    561     for (int row = 0; row < row_count; row ++) {
    562         FX_LPBYTE scan_line = data_buf + row * row_size;
    563         if ((row + 1) * row_size > (int)data_size) {
    564             row_size = last_row_size;
    565         }
    566         TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns);
    567     }
    568 }
    569 class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder
    570 {
    571 public:
    572     CCodec_FlateScanlineDecoder();
    573     ~CCodec_FlateScanlineDecoder();
    574     FX_BOOL		Create(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, int nComps, int bpc,
    575                        int predictor, int Colors, int BitsPerComponent, int Columns);
    576     virtual void		Destroy()
    577     {
    578         delete this;
    579     }
    580     virtual void		v_DownScale(int dest_width, int dest_height) {}
    581     virtual FX_BOOL		v_Rewind();
    582     virtual FX_LPBYTE	v_GetNextLine();
    583     virtual FX_DWORD	GetSrcOffset();
    584     void*				m_pFlate;
    585     FX_LPCBYTE			m_SrcBuf;
    586     FX_DWORD			m_SrcSize;
    587     FX_LPBYTE			m_pScanline;
    588     FX_LPBYTE			m_pLastLine;
    589     FX_LPBYTE			m_pPredictBuffer;
    590     FX_LPBYTE			m_pPredictRaw;
    591     int					m_Predictor;
    592     int					m_Colors, m_BitsPerComponent, m_Columns, m_PredictPitch, m_LeftOver;
    593 };
    594 CCodec_FlateScanlineDecoder::CCodec_FlateScanlineDecoder()
    595 {
    596     m_pFlate = NULL;
    597     m_pScanline = NULL;
    598     m_pLastLine = NULL;
    599     m_pPredictBuffer = NULL;
    600     m_pPredictRaw = NULL;
    601     m_LeftOver = 0;
    602 }
    603 CCodec_FlateScanlineDecoder::~CCodec_FlateScanlineDecoder()
    604 {
    605     if (m_pScanline) {
    606         FX_Free(m_pScanline);
    607     }
    608     if (m_pLastLine) {
    609         FX_Free(m_pLastLine);
    610     }
    611     if (m_pPredictBuffer) {
    612         FX_Free(m_pPredictBuffer);
    613     }
    614     if (m_pPredictRaw) {
    615         FX_Free(m_pPredictRaw);
    616     }
    617     if (m_pFlate) {
    618         FPDFAPI_FlateEnd(m_pFlate);
    619     }
    620 }
    621 FX_BOOL CCodec_FlateScanlineDecoder::Create(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height,
    622         int nComps, int bpc, int predictor, int Colors, int BitsPerComponent, int Columns)
    623 {
    624     m_SrcBuf = src_buf;
    625     m_SrcSize = src_size;
    626     m_OutputWidth = m_OrigWidth = width;
    627     m_OutputHeight = m_OrigHeight = height;
    628     m_nComps = nComps;
    629     m_bpc = bpc;
    630     m_bColorTransformed = FALSE;
    631     m_Pitch = (width * nComps * bpc + 7) / 8;
    632     m_pScanline = FX_Alloc(FX_BYTE, m_Pitch);
    633     if (m_pScanline == NULL) {
    634         return FALSE;
    635     }
    636     m_Predictor = 0;
    637     if (predictor) {
    638         if (predictor >= 10) {
    639             m_Predictor = 2;
    640         } else if (predictor == 2) {
    641             m_Predictor = 1;
    642         }
    643         if (m_Predictor) {
    644             if (BitsPerComponent * Colors * Columns == 0) {
    645                 BitsPerComponent = m_bpc;
    646                 Colors = m_nComps;
    647                 Columns = m_OrigWidth;
    648             }
    649             m_Colors = Colors;
    650             m_BitsPerComponent = BitsPerComponent;
    651             m_Columns = Columns;
    652             m_PredictPitch = (m_BitsPerComponent * m_Colors * m_Columns + 7) / 8;
    653             m_pLastLine = FX_Alloc(FX_BYTE, m_PredictPitch);
    654             if (m_pLastLine == NULL) {
    655                 return FALSE;
    656             }
    657             FXSYS_memset32(m_pLastLine, 0, m_PredictPitch);
    658             m_pPredictRaw = FX_Alloc(FX_BYTE, m_PredictPitch + 1);
    659             if (m_pPredictRaw == NULL) {
    660                 return FALSE;
    661             }
    662             m_pPredictBuffer = FX_Alloc(FX_BYTE, m_PredictPitch);
    663             if (m_pPredictBuffer == NULL) {
    664                 return FALSE;
    665             }
    666         }
    667     }
    668     return TRUE;
    669 }
    670 FX_BOOL CCodec_FlateScanlineDecoder::v_Rewind()
    671 {
    672     if (m_pFlate) {
    673         FPDFAPI_FlateEnd(m_pFlate);
    674     }
    675     m_pFlate = FPDFAPI_FlateInit(my_alloc_func, my_free_func);
    676     if (m_pFlate == NULL) {
    677         return FALSE;
    678     }
    679     FPDFAPI_FlateInput(m_pFlate, m_SrcBuf, m_SrcSize);
    680     m_LeftOver = 0;
    681     return TRUE;
    682 }
    683 FX_LPBYTE CCodec_FlateScanlineDecoder::v_GetNextLine()
    684 {
    685     if (m_Predictor) {
    686         if (m_Pitch == m_PredictPitch) {
    687             if (m_Predictor == 2) {
    688                 FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1);
    689                 PNG_PredictLine(m_pScanline, m_pPredictRaw, m_pLastLine, m_BitsPerComponent, m_Colors, m_Columns);
    690                 FXSYS_memcpy32(m_pLastLine, m_pScanline, m_PredictPitch);
    691             } else {
    692                 FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch);
    693                 TIFF_PredictLine(m_pScanline, m_PredictPitch, m_bpc, m_nComps, m_OutputWidth);
    694             }
    695         } else {
    696             int bytes_to_go = m_Pitch;
    697             int read_leftover = m_LeftOver > bytes_to_go ? bytes_to_go : m_LeftOver;
    698             if (read_leftover) {
    699                 FXSYS_memcpy32(m_pScanline, m_pPredictBuffer + m_PredictPitch - m_LeftOver, read_leftover);
    700                 m_LeftOver -= read_leftover;
    701                 bytes_to_go -= read_leftover;
    702             }
    703             while (bytes_to_go) {
    704                 if (m_Predictor == 2) {
    705                     FPDFAPI_FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1);
    706                     PNG_PredictLine(m_pPredictBuffer, m_pPredictRaw, m_pLastLine, m_BitsPerComponent, m_Colors, m_Columns);
    707                     FXSYS_memcpy32(m_pLastLine, m_pPredictBuffer, m_PredictPitch);
    708                 } else {
    709                     FPDFAPI_FlateOutput(m_pFlate, m_pPredictBuffer, m_PredictPitch);
    710                     TIFF_PredictLine(m_pPredictBuffer, m_PredictPitch, m_BitsPerComponent, m_Colors, m_Columns);
    711                 }
    712                 int read_bytes = m_PredictPitch > bytes_to_go ? bytes_to_go : m_PredictPitch;
    713                 FXSYS_memcpy32(m_pScanline + m_Pitch - bytes_to_go, m_pPredictBuffer, read_bytes);
    714                 m_LeftOver += m_PredictPitch - read_bytes;
    715                 bytes_to_go -= read_bytes;
    716             }
    717         }
    718     } else {
    719         FPDFAPI_FlateOutput(m_pFlate, m_pScanline, m_Pitch);
    720     }
    721     return m_pScanline;
    722 }
    723 FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset()
    724 {
    725     return FPDFAPI_FlateGetTotalIn(m_pFlate);
    726 }
    727 static void FlateUncompress(FX_LPCBYTE src_buf, FX_DWORD src_size, FX_DWORD orig_size,
    728                             FX_LPBYTE& dest_buf, FX_DWORD& dest_size, FX_DWORD& offset)
    729 {
    730     FX_DWORD guess_size = orig_size ? orig_size : src_size * 2;
    731     FX_DWORD alloc_step = orig_size ? 10240 : (src_size < 10240 ? 10240 : src_size);
    732     static const FX_DWORD kMaxInitialAllocSize = 10000000;
    733     if (guess_size > kMaxInitialAllocSize) {
    734         guess_size = kMaxInitialAllocSize;
    735         alloc_step = kMaxInitialAllocSize;
    736     }
    737     FX_LPBYTE guess_buf = FX_Alloc(FX_BYTE, guess_size + 1);
    738     if (!guess_buf) {
    739         dest_buf = NULL;
    740         dest_size = 0;
    741         return;
    742     }
    743     guess_buf[guess_size] = '\0';
    744     FX_BOOL useOldImpl = src_size < 10240;
    745     void* context = FPDFAPI_FlateInit(my_alloc_func, my_free_func);
    746     if (context == NULL) {
    747         dest_buf = NULL;
    748         dest_size = 0;
    749         return ;
    750     }
    751     FPDFAPI_FlateInput(context, src_buf, src_size);
    752     CFX_ArrayTemplate<FX_LPBYTE> result_tmp_bufs;
    753     FX_LPBYTE buf = guess_buf;
    754     FX_DWORD buf_size = guess_size;
    755     FX_DWORD last_buf_size = buf_size;
    756     while (1) {
    757         FX_INT32 ret = FPDFAPI_FlateOutput(context, buf, buf_size);
    758         FX_INT32 avail_buf_size = FPDFAPI_FlateGetAvailOut(context);
    759         if (!useOldImpl) {
    760             if (ret != Z_OK) {
    761                 last_buf_size = buf_size - avail_buf_size;
    762                 result_tmp_bufs.Add(buf);
    763                 break;
    764             }
    765             if (avail_buf_size == 0) {
    766                 result_tmp_bufs.Add(buf);
    767                 buf = NULL;
    768                 buf = FX_Alloc(FX_BYTE, buf_size + 1);
    769                 if (!buf) {
    770                     dest_buf = NULL;
    771                     dest_size = 0;
    772                     return;
    773                 }
    774                 buf[buf_size] = '\0';
    775             } else {
    776                 last_buf_size = buf_size - avail_buf_size;
    777                 result_tmp_bufs.Add(buf);
    778                 buf = NULL;
    779                 break;
    780             }
    781         } else {
    782             if (ret != Z_OK) {
    783                 break;
    784             }
    785             if (avail_buf_size == 0) {
    786                 FX_DWORD old_size = guess_size;
    787                 guess_size += alloc_step;
    788                 if (guess_size < old_size || guess_size + 1 < guess_size) {
    789                     dest_buf = NULL;
    790                     dest_size = 0;
    791                     return;
    792                 }
    793                 guess_buf = FX_Realloc(FX_BYTE, guess_buf, guess_size + 1);
    794                 if (!guess_buf) {
    795                     dest_buf = NULL;
    796                     dest_size = 0;
    797                     return;
    798                 }
    799                 guess_buf[guess_size] = '\0';
    800                 buf = guess_buf + old_size;
    801                 buf_size = guess_size - old_size;
    802             } else {
    803                 break;
    804             }
    805         }
    806     }
    807     dest_size = FPDFAPI_FlateGetTotalOut(context);
    808     offset = FPDFAPI_FlateGetTotalIn(context);
    809     if (!useOldImpl) {
    810         if (result_tmp_bufs.GetSize() == 1) {
    811             dest_buf = result_tmp_bufs[0];
    812         } else {
    813             FX_LPBYTE result_buf = FX_Alloc(FX_BYTE, dest_size);
    814             if (!result_buf) {
    815                 dest_buf = NULL;
    816                 dest_size = 0;
    817                 return;
    818             }
    819             FX_DWORD result_pos = 0;
    820             for (FX_INT32 i = 0; i < result_tmp_bufs.GetSize(); i++) {
    821                 FX_LPBYTE tmp_buf = result_tmp_bufs[i];
    822                 FX_DWORD tmp_buf_size = buf_size;
    823                 if (i == result_tmp_bufs.GetSize() - 1) {
    824                     tmp_buf_size = last_buf_size;
    825                 }
    826                 FXSYS_memcpy32(result_buf + result_pos, tmp_buf, tmp_buf_size);
    827                 result_pos += tmp_buf_size;
    828                 FX_Free(tmp_buf);
    829                 tmp_buf = NULL;
    830                 result_tmp_bufs[i] = NULL;
    831             }
    832             dest_buf = result_buf;
    833         }
    834     } else {
    835         if (guess_size / 2 > dest_size) {
    836             guess_buf = FX_Realloc(FX_BYTE, guess_buf, dest_size + 1);
    837             if (!guess_buf) {
    838                 dest_buf = NULL;
    839                 dest_size = 0;
    840                 return;
    841             }
    842             guess_size = dest_size;
    843             guess_buf[guess_size] = '\0';
    844         }
    845         dest_buf = guess_buf;
    846     }
    847     FPDFAPI_FlateEnd(context);
    848     context = NULL;
    849 }
    850 ICodec_ScanlineDecoder*	CCodec_FlateModule::CreateDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height,
    851         int nComps, int bpc, int predictor, int Colors, int BitsPerComponent, int Columns)
    852 {
    853     CCodec_FlateScanlineDecoder* pDecoder = FX_NEW CCodec_FlateScanlineDecoder;
    854     if (pDecoder == NULL) {
    855         return NULL;
    856     }
    857     pDecoder->Create(src_buf, src_size, width, height, nComps, bpc, predictor, Colors, BitsPerComponent, Columns);
    858     return pDecoder;
    859 }
    860 FX_DWORD CCodec_FlateModule::FlateOrLZWDecode(FX_BOOL bLZW, const FX_BYTE* src_buf, FX_DWORD src_size, FX_BOOL bEarlyChange,
    861         int predictor, int Colors, int BitsPerComponent, int Columns,
    862         FX_DWORD estimated_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
    863 {
    864     CLZWDecoder* pDecoder = NULL;
    865     dest_buf = NULL;
    866     FX_DWORD offset = 0;
    867     int predictor_type = 0;
    868     if (predictor) {
    869         if (predictor >= 10) {
    870             predictor_type = 2;
    871         } else if (predictor == 2) {
    872             predictor_type = 1;
    873         }
    874     }
    875     if (bLZW) {
    876         pDecoder = FX_NEW CLZWDecoder;
    877         if (pDecoder == NULL) {
    878             return -1;
    879         }
    880         dest_size = (FX_DWORD) - 1;
    881         offset = src_size;
    882         int err = pDecoder->Decode(NULL, dest_size, src_buf, offset, bEarlyChange);
    883         delete pDecoder;
    884         if (err || dest_size == 0 || dest_size + 1 < dest_size) {
    885             return (FX_DWORD) - 1;
    886         }
    887         pDecoder = FX_NEW CLZWDecoder;
    888         if (pDecoder == NULL) {
    889             return -1;
    890         }
    891         dest_buf = FX_Alloc( FX_BYTE, dest_size + 1);
    892         if (dest_buf == NULL) {
    893             return -1;
    894         }
    895         dest_buf[dest_size] = '\0';
    896         pDecoder->Decode(dest_buf, dest_size, src_buf, offset, bEarlyChange);
    897         delete pDecoder;
    898     } else {
    899         FlateUncompress(src_buf, src_size, estimated_size, dest_buf, dest_size, offset);
    900     }
    901     if (predictor_type == 0) {
    902         return offset;
    903     }
    904     if (predictor_type == 2) {
    905         PNG_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns);
    906     } else if (predictor_type == 1) {
    907         TIFF_Predictor(dest_buf, dest_size, Colors, BitsPerComponent, Columns);
    908     }
    909     return offset;
    910 }
    911 FX_BOOL CCodec_FlateModule::Encode(const FX_BYTE* src_buf, FX_DWORD src_size,
    912                                    int predictor, int Colors, int BitsPerComponent, int Columns,
    913                                    FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
    914 {
    915     if (predictor != 2 && predictor < 10) {
    916         return Encode(src_buf, src_size, dest_buf, dest_size);
    917     }
    918     FX_BOOL ret = FALSE;
    919     FX_LPBYTE pSrcBuf = NULL;
    920     pSrcBuf = FX_Alloc(FX_BYTE, src_size);
    921     if (pSrcBuf == NULL) {
    922         return FALSE;
    923     }
    924     FXSYS_memcpy32(pSrcBuf, src_buf, src_size);
    925     if (predictor == 2) {
    926         TIFF_PredictorEncode(pSrcBuf, src_size, Colors, BitsPerComponent, Columns);
    927     } else if (predictor >= 10) {
    928         PNG_PredictorEncode(pSrcBuf, src_size, predictor, Colors, BitsPerComponent, Columns);
    929     }
    930     ret = Encode(pSrcBuf, src_size, dest_buf, dest_size);
    931     FX_Free(pSrcBuf);
    932     return ret;
    933 }
    934 FX_BOOL CCodec_FlateModule::Encode(FX_LPCBYTE src_buf, FX_DWORD src_size, FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
    935 {
    936     dest_size = src_size + src_size / 1000 + 12;
    937     dest_buf = FX_Alloc( FX_BYTE, dest_size);
    938     if (dest_buf == NULL) {
    939         return FALSE;
    940     }
    941     unsigned long temp_size = dest_size;
    942     FPDFAPI_FlateCompress(dest_buf, &temp_size, src_buf, src_size);
    943     dest_size = (FX_DWORD)temp_size;
    944     return TRUE;
    945 }
    946