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