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