// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fxcodec/codec/codec_int.h"

#include <algorithm>
#include <memory>
#include <utility>
#include <vector>

#include "core/fxcodec/codec/ccodec_flatemodule.h"
#include "core/fxcodec/codec/ccodec_scanlinedecoder.h"
#include "core/fxcrt/fx_extension.h"
#include "third_party/base/numerics/safe_conversions.h"
#include "third_party/base/ptr_util.h"

#if defined(USE_SYSTEM_ZLIB)
#include <zlib.h>
#else
#include "third_party/zlib/zlib.h"
#endif

extern "C" {

static void* my_alloc_func(void* opaque,
                           unsigned int items,
                           unsigned int size) {
  return FX_Alloc2D(uint8_t, items, size);
}

static void my_free_func(void* opaque, void* address) {
  FX_Free(address);
}

}  // extern "C"

namespace {

uint32_t FlateGetPossiblyTruncatedTotalOut(void* context) {
  return pdfium::base::saturated_cast<uint32_t>(
      static_cast<z_stream*>(context)->total_out);
}

uint32_t FlateGetPossiblyTruncatedTotalIn(void* context) {
  return pdfium::base::saturated_cast<uint32_t>(
      static_cast<z_stream*>(context)->total_in);
}

bool FlateCompress(unsigned char* dest_buf,
                   unsigned long* dest_size,
                   const unsigned char* src_buf,
                   uint32_t src_size) {
  return compress(dest_buf, dest_size, src_buf, src_size) == Z_OK;
}

void* FlateInit() {
  z_stream* p = FX_Alloc(z_stream, 1);
  memset(p, 0, sizeof(z_stream));
  p->zalloc = my_alloc_func;
  p->zfree = my_free_func;
  inflateInit(p);
  return p;
}

void FlateInput(void* context,
                const unsigned char* src_buf,
                uint32_t src_size) {
  static_cast<z_stream*>(context)->next_in =
      const_cast<unsigned char*>(src_buf);
  static_cast<z_stream*>(context)->avail_in = src_size;
}

uint32_t FlateOutput(void* context,
                     unsigned char* dest_buf,
                     uint32_t dest_size) {
  static_cast<z_stream*>(context)->next_out = dest_buf;
  static_cast<z_stream*>(context)->avail_out = dest_size;
  uint32_t pre_pos = FlateGetPossiblyTruncatedTotalOut(context);
  int ret = inflate(static_cast<z_stream*>(context), Z_SYNC_FLUSH);

  uint32_t post_pos = FlateGetPossiblyTruncatedTotalOut(context);
  ASSERT(post_pos >= pre_pos);

  uint32_t written = post_pos - pre_pos;
  if (written < dest_size)
    memset(dest_buf + written, '\0', dest_size - written);

  return ret;
}

uint32_t FlateGetAvailOut(void* context) {
  return static_cast<z_stream*>(context)->avail_out;
}

void FlateEnd(void* context) {
  inflateEnd(static_cast<z_stream*>(context));
  static_cast<z_stream*>(context)->zfree(0, context);
}

class CLZWDecoder {
 public:
  int Decode(uint8_t* output,
             uint32_t& outlen,
             const uint8_t* input,
             uint32_t& size,
             bool bEarlyChange);

 private:
  void AddCode(uint32_t prefix_code, uint8_t append_char);
  void DecodeString(uint32_t code);

  uint32_t m_InPos;
  uint32_t m_OutPos;
  uint8_t* m_pOutput;
  const uint8_t* m_pInput;
  bool m_Early;
  uint32_t m_CodeArray[5021];
  uint32_t m_nCodes;
  uint8_t m_DecodeStack[4000];
  uint32_t m_StackLen;
  int m_CodeLen;
};

void CLZWDecoder::AddCode(uint32_t prefix_code, uint8_t append_char) {
  if (m_nCodes + m_Early == 4094) {
    return;
  }
  m_CodeArray[m_nCodes++] = (prefix_code << 16) | append_char;
  if (m_nCodes + m_Early == 512 - 258) {
    m_CodeLen = 10;
  } else if (m_nCodes + m_Early == 1024 - 258) {
    m_CodeLen = 11;
  } else if (m_nCodes + m_Early == 2048 - 258) {
    m_CodeLen = 12;
  }
}
void CLZWDecoder::DecodeString(uint32_t code) {
  while (1) {
    int index = code - 258;
    if (index < 0 || index >= (int)m_nCodes) {
      break;
    }
    uint32_t data = m_CodeArray[index];
    if (m_StackLen >= sizeof(m_DecodeStack)) {
      return;
    }
    m_DecodeStack[m_StackLen++] = (uint8_t)data;
    code = data >> 16;
  }
  if (m_StackLen >= sizeof(m_DecodeStack)) {
    return;
  }
  m_DecodeStack[m_StackLen++] = (uint8_t)code;
}
int CLZWDecoder::Decode(uint8_t* dest_buf,
                        uint32_t& dest_size,
                        const uint8_t* src_buf,
                        uint32_t& src_size,
                        bool bEarlyChange) {
  m_CodeLen = 9;
  m_InPos = 0;
  m_OutPos = 0;
  m_pInput = src_buf;
  m_pOutput = dest_buf;
  m_Early = bEarlyChange ? 1 : 0;
  m_nCodes = 0;
  uint32_t old_code = 0xFFFFFFFF;
  uint8_t last_char = 0;
  while (1) {
    if (m_InPos + m_CodeLen > src_size * 8) {
      break;
    }
    int byte_pos = m_InPos / 8;
    int bit_pos = m_InPos % 8, bit_left = m_CodeLen;
    uint32_t code = 0;
    if (bit_pos) {
      bit_left -= 8 - bit_pos;
      code = (m_pInput[byte_pos++] & ((1 << (8 - bit_pos)) - 1)) << bit_left;
    }
    if (bit_left < 8) {
      code |= m_pInput[byte_pos] >> (8 - bit_left);
    } else {
      bit_left -= 8;
      code |= m_pInput[byte_pos++] << bit_left;
      if (bit_left) {
        code |= m_pInput[byte_pos] >> (8 - bit_left);
      }
    }
    m_InPos += m_CodeLen;
    if (code == 257)
      break;
    if (code < 256) {
      if (m_OutPos == dest_size) {
        return -5;
      }
      if (m_pOutput) {
        m_pOutput[m_OutPos] = (uint8_t)code;
      }
      m_OutPos++;
      last_char = (uint8_t)code;
      if (old_code != 0xFFFFFFFF)
        AddCode(old_code, last_char);
      old_code = code;
    } else if (code == 256) {
      m_CodeLen = 9;
      m_nCodes = 0;
      old_code = 0xFFFFFFFF;
    } else {
      // Else 257 or greater.
      if (old_code == 0xFFFFFFFF)
        return 2;

      m_StackLen = 0;
      if (code >= m_nCodes + 258) {
        if (m_StackLen < sizeof(m_DecodeStack)) {
          m_DecodeStack[m_StackLen++] = last_char;
        }
        DecodeString(old_code);
      } else {
        DecodeString(code);
      }
      if (m_OutPos + m_StackLen > dest_size) {
        return -5;
      }
      if (m_pOutput) {
        for (uint32_t i = 0; i < m_StackLen; i++) {
          m_pOutput[m_OutPos + i] = m_DecodeStack[m_StackLen - i - 1];
        }
      }
      m_OutPos += m_StackLen;
      last_char = m_DecodeStack[m_StackLen - 1];
      if (old_code < 256) {
        AddCode(old_code, last_char);
      } else if (old_code - 258 >= m_nCodes) {
        dest_size = m_OutPos;
        src_size = (m_InPos + 7) / 8;
        return 0;
      } else {
        AddCode(old_code, last_char);
      }
      old_code = code;
    }
  }
  dest_size = m_OutPos;
  src_size = (m_InPos + 7) / 8;
  return 0;
}

uint8_t PathPredictor(int a, int b, int c) {
  int p = a + b - c;
  int pa = abs(p - a);
  int pb = abs(p - b);
  int pc = abs(p - c);
  if (pa <= pb && pa <= pc)
    return (uint8_t)a;
  if (pb <= pc)
    return (uint8_t)b;
  return (uint8_t)c;
}

void PNG_PredictorEncode(uint8_t** data_buf, uint32_t* data_size) {
  const int row_size = 7;
  const int row_count = (*data_size + row_size - 1) / row_size;
  const int last_row_size = *data_size % row_size;
  uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size + 1, row_count);
  int byte_cnt = 0;
  uint8_t* pSrcData = *data_buf;
  uint8_t* pDestData = dest_buf;
  for (int row = 0; row < row_count; row++) {
    for (int byte = 0; byte < row_size && byte_cnt < (int)*data_size; byte++) {
      pDestData[0] = 2;
      uint8_t up = 0;
      if (row)
        up = pSrcData[byte - row_size];
      pDestData[byte + 1] = pSrcData[byte] - up;
      ++byte_cnt;
    }
    pDestData += (row_size + 1);
    pSrcData += row_size;
  }
  FX_Free(*data_buf);
  *data_buf = dest_buf;
  *data_size = (row_size + 1) * row_count -
               (last_row_size > 0 ? (row_size - last_row_size) : 0);
}

void PNG_PredictLine(uint8_t* pDestData,
                     const uint8_t* pSrcData,
                     const uint8_t* pLastLine,
                     int bpc,
                     int nColors,
                     int nPixels) {
  int row_size = (nPixels * bpc * nColors + 7) / 8;
  int BytesPerPixel = (bpc * nColors + 7) / 8;
  uint8_t tag = pSrcData[0];
  if (tag == 0) {
    memmove(pDestData, pSrcData + 1, row_size);
    return;
  }
  for (int byte = 0; byte < row_size; byte++) {
    uint8_t raw_byte = pSrcData[byte + 1];
    switch (tag) {
      case 1: {
        uint8_t left = 0;
        if (byte >= BytesPerPixel) {
          left = pDestData[byte - BytesPerPixel];
        }
        pDestData[byte] = raw_byte + left;
        break;
      }
      case 2: {
        uint8_t up = 0;
        if (pLastLine) {
          up = pLastLine[byte];
        }
        pDestData[byte] = raw_byte + up;
        break;
      }
      case 3: {
        uint8_t left = 0;
        if (byte >= BytesPerPixel) {
          left = pDestData[byte - BytesPerPixel];
        }
        uint8_t up = 0;
        if (pLastLine) {
          up = pLastLine[byte];
        }
        pDestData[byte] = raw_byte + (up + left) / 2;
        break;
      }
      case 4: {
        uint8_t left = 0;
        if (byte >= BytesPerPixel) {
          left = pDestData[byte - BytesPerPixel];
        }
        uint8_t up = 0;
        if (pLastLine) {
          up = pLastLine[byte];
        }
        uint8_t upper_left = 0;
        if (byte >= BytesPerPixel && pLastLine) {
          upper_left = pLastLine[byte - BytesPerPixel];
        }
        pDestData[byte] = raw_byte + PathPredictor(left, up, upper_left);
        break;
      }
      default:
        pDestData[byte] = raw_byte;
        break;
    }
  }
}

bool PNG_Predictor(uint8_t*& data_buf,
                   uint32_t& data_size,
                   int Colors,
                   int BitsPerComponent,
                   int Columns) {
  const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8;
  const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8;
  if (row_size <= 0)
    return false;
  const int row_count = (data_size + row_size) / (row_size + 1);
  if (row_count <= 0)
    return false;
  const int last_row_size = data_size % (row_size + 1);
  uint8_t* dest_buf = FX_Alloc2D(uint8_t, row_size, row_count);
  int byte_cnt = 0;
  uint8_t* pSrcData = data_buf;
  uint8_t* pDestData = dest_buf;
  for (int row = 0; row < row_count; row++) {
    uint8_t tag = pSrcData[0];
    byte_cnt++;
    if (tag == 0) {
      int move_size = row_size;
      if ((row + 1) * (move_size + 1) > (int)data_size) {
        move_size = last_row_size - 1;
      }
      memmove(pDestData, pSrcData + 1, move_size);
      pSrcData += move_size + 1;
      pDestData += move_size;
      byte_cnt += move_size;
      continue;
    }
    for (int byte = 0; byte < row_size && byte_cnt < (int)data_size; byte++) {
      uint8_t raw_byte = pSrcData[byte + 1];
      switch (tag) {
        case 1: {
          uint8_t left = 0;
          if (byte >= BytesPerPixel) {
            left = pDestData[byte - BytesPerPixel];
          }
          pDestData[byte] = raw_byte + left;
          break;
        }
        case 2: {
          uint8_t up = 0;
          if (row) {
            up = pDestData[byte - row_size];
          }
          pDestData[byte] = raw_byte + up;
          break;
        }
        case 3: {
          uint8_t left = 0;
          if (byte >= BytesPerPixel) {
            left = pDestData[byte - BytesPerPixel];
          }
          uint8_t up = 0;
          if (row) {
            up = pDestData[byte - row_size];
          }
          pDestData[byte] = raw_byte + (up + left) / 2;
          break;
        }
        case 4: {
          uint8_t left = 0;
          if (byte >= BytesPerPixel) {
            left = pDestData[byte - BytesPerPixel];
          }
          uint8_t up = 0;
          if (row) {
            up = pDestData[byte - row_size];
          }
          uint8_t upper_left = 0;
          if (byte >= BytesPerPixel && row) {
            upper_left = pDestData[byte - row_size - BytesPerPixel];
          }
          pDestData[byte] = raw_byte + PathPredictor(left, up, upper_left);
          break;
        }
        default:
          pDestData[byte] = raw_byte;
          break;
      }
      byte_cnt++;
    }
    pSrcData += row_size + 1;
    pDestData += row_size;
  }
  FX_Free(data_buf);
  data_buf = dest_buf;
  data_size = row_size * row_count -
              (last_row_size > 0 ? (row_size + 1 - last_row_size) : 0);
  return true;
}

void TIFF_PredictLine(uint8_t* dest_buf,
                      uint32_t row_size,
                      int BitsPerComponent,
                      int Colors,
                      int Columns) {
  if (BitsPerComponent == 1) {
    int row_bits = std::min(BitsPerComponent * Colors * Columns,
                            pdfium::base::checked_cast<int>(row_size * 8));
    int index_pre = 0;
    int col_pre = 0;
    for (int i = 1; i < row_bits; i++) {
      int col = i % 8;
      int index = i / 8;
      if (((dest_buf[index] >> (7 - col)) & 1) ^
          ((dest_buf[index_pre] >> (7 - col_pre)) & 1)) {
        dest_buf[index] |= 1 << (7 - col);
      } else {
        dest_buf[index] &= ~(1 << (7 - col));
      }
      index_pre = index;
      col_pre = col;
    }
    return;
  }
  int BytesPerPixel = BitsPerComponent * Colors / 8;
  if (BitsPerComponent == 16) {
    for (uint32_t i = BytesPerPixel; i + 1 < row_size; i += 2) {
      uint16_t pixel =
          (dest_buf[i - BytesPerPixel] << 8) | dest_buf[i - BytesPerPixel + 1];
      pixel += (dest_buf[i] << 8) | dest_buf[i + 1];
      dest_buf[i] = pixel >> 8;
      dest_buf[i + 1] = (uint8_t)pixel;
    }
  } else {
    for (uint32_t i = BytesPerPixel; i < row_size; i++) {
      dest_buf[i] += dest_buf[i - BytesPerPixel];
    }
  }
}

bool TIFF_Predictor(uint8_t*& data_buf,
                    uint32_t& data_size,
                    int Colors,
                    int BitsPerComponent,
                    int Columns) {
  int row_size = (Colors * BitsPerComponent * Columns + 7) / 8;
  if (row_size == 0)
    return false;
  const int row_count = (data_size + row_size - 1) / row_size;
  const int last_row_size = data_size % row_size;
  for (int row = 0; row < row_count; row++) {
    uint8_t* scan_line = data_buf + row * row_size;
    if ((row + 1) * row_size > (int)data_size) {
      row_size = last_row_size;
    }
    TIFF_PredictLine(scan_line, row_size, BitsPerComponent, Colors, Columns);
  }
  return true;
}

void FlateUncompress(const uint8_t* src_buf,
                     uint32_t src_size,
                     uint32_t orig_size,
                     uint8_t*& dest_buf,
                     uint32_t& dest_size,
                     uint32_t& offset) {
  dest_buf = nullptr;
  dest_size = 0;
  void* context = FlateInit();
  if (!context)
    return;

  FlateInput(context, src_buf, src_size);

  const uint32_t kMaxInitialAllocSize = 10000000;
  uint32_t guess_size = orig_size ? orig_size : src_size * 2;
  guess_size = std::min(guess_size, kMaxInitialAllocSize);

  uint32_t buf_size = guess_size;
  uint32_t last_buf_size = buf_size;
  std::unique_ptr<uint8_t, FxFreeDeleter> guess_buf(
      FX_Alloc(uint8_t, guess_size + 1));
  guess_buf.get()[guess_size] = '\0';

  std::vector<uint8_t*> result_tmp_bufs;
  uint8_t* cur_buf = guess_buf.release();
  while (1) {
    uint32_t ret = FlateOutput(context, cur_buf, buf_size);
    uint32_t avail_buf_size = FlateGetAvailOut(context);
    if (ret != Z_OK || avail_buf_size != 0) {
      last_buf_size = buf_size - avail_buf_size;
      result_tmp_bufs.push_back(cur_buf);
      break;
    }
    result_tmp_bufs.push_back(cur_buf);
    cur_buf = FX_Alloc(uint8_t, buf_size + 1);
    cur_buf[buf_size] = '\0';
  }

  // The TotalOut size returned from the library may not be big enough to
  // handle the content the library returns. We can only handle items
  // up to 4GB in size.
  dest_size = FlateGetPossiblyTruncatedTotalOut(context);
  offset = FlateGetPossiblyTruncatedTotalIn(context);
  if (result_tmp_bufs.size() == 1) {
    dest_buf = result_tmp_bufs[0];
  } else {
    uint8_t* result_buf = FX_Alloc(uint8_t, dest_size);
    uint32_t result_pos = 0;
    uint32_t remaining = dest_size;
    for (size_t i = 0; i < result_tmp_bufs.size(); i++) {
      uint8_t* tmp_buf = result_tmp_bufs[i];
      uint32_t tmp_buf_size = buf_size;
      if (i == result_tmp_bufs.size() - 1)
        tmp_buf_size = last_buf_size;

      uint32_t cp_size = std::min(tmp_buf_size, remaining);
      memcpy(result_buf + result_pos, tmp_buf, cp_size);
      result_pos += cp_size;
      remaining -= cp_size;

      FX_Free(result_tmp_bufs[i]);
    }
    dest_buf = result_buf;
  }
  FlateEnd(context);
}

}  // namespace

class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder {
 public:
  CCodec_FlateScanlineDecoder();
  ~CCodec_FlateScanlineDecoder() override;

  void Create(const uint8_t* src_buf,
              uint32_t src_size,
              int width,
              int height,
              int nComps,
              int bpc,
              int predictor,
              int Colors,
              int BitsPerComponent,
              int Columns);

  // CCodec_ScanlineDecoder
  bool v_Rewind() override;
  uint8_t* v_GetNextLine() override;
  uint32_t GetSrcOffset() override;

  void* m_pFlate;
  const uint8_t* m_SrcBuf;
  uint32_t m_SrcSize;
  uint8_t* m_pScanline;
  uint8_t* m_pLastLine;
  uint8_t* m_pPredictBuffer;
  uint8_t* m_pPredictRaw;
  int m_Predictor;
  int m_Colors;
  int m_BitsPerComponent;
  int m_Columns;
  uint32_t m_PredictPitch;
  size_t m_LeftOver;
};

CCodec_FlateScanlineDecoder::CCodec_FlateScanlineDecoder() {
  m_pFlate = nullptr;
  m_pScanline = nullptr;
  m_pLastLine = nullptr;
  m_pPredictBuffer = nullptr;
  m_pPredictRaw = nullptr;
  m_LeftOver = 0;
}

CCodec_FlateScanlineDecoder::~CCodec_FlateScanlineDecoder() {
  FX_Free(m_pScanline);
  FX_Free(m_pLastLine);
  FX_Free(m_pPredictBuffer);
  FX_Free(m_pPredictRaw);
  if (m_pFlate)
    FlateEnd(m_pFlate);
}

void CCodec_FlateScanlineDecoder::Create(const uint8_t* src_buf,
                                         uint32_t src_size,
                                         int width,
                                         int height,
                                         int nComps,
                                         int bpc,
                                         int predictor,
                                         int Colors,
                                         int BitsPerComponent,
                                         int Columns) {
  m_SrcBuf = src_buf;
  m_SrcSize = src_size;
  m_OutputWidth = m_OrigWidth = width;
  m_OutputHeight = m_OrigHeight = height;
  m_nComps = nComps;
  m_bpc = bpc;
  m_Pitch = (static_cast<uint32_t>(width) * nComps * bpc + 7) / 8;
  m_pScanline = FX_Alloc(uint8_t, m_Pitch);
  m_Predictor = 0;
  if (predictor) {
    if (predictor >= 10) {
      m_Predictor = 2;
    } else if (predictor == 2) {
      m_Predictor = 1;
    }
    if (m_Predictor) {
      if (BitsPerComponent * Colors * Columns == 0) {
        BitsPerComponent = m_bpc;
        Colors = m_nComps;
        Columns = m_OrigWidth;
      }
      m_Colors = Colors;
      m_BitsPerComponent = BitsPerComponent;
      m_Columns = Columns;
      m_PredictPitch =
          (static_cast<uint32_t>(m_BitsPerComponent) * m_Colors * m_Columns +
           7) /
          8;
      m_pLastLine = FX_Alloc(uint8_t, m_PredictPitch);
      m_pPredictRaw = FX_Alloc(uint8_t, m_PredictPitch + 1);
      m_pPredictBuffer = FX_Alloc(uint8_t, m_PredictPitch);
    }
  }
}

bool CCodec_FlateScanlineDecoder::v_Rewind() {
  if (m_pFlate)
    FlateEnd(m_pFlate);

  m_pFlate = FlateInit();
  if (!m_pFlate)
    return false;

  FlateInput(m_pFlate, m_SrcBuf, m_SrcSize);
  m_LeftOver = 0;
  return true;
}

uint8_t* CCodec_FlateScanlineDecoder::v_GetNextLine() {
  if (m_Predictor) {
    if (m_Pitch == m_PredictPitch) {
      if (m_Predictor == 2) {
        FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1);
        PNG_PredictLine(m_pScanline, m_pPredictRaw, m_pLastLine,
                        m_BitsPerComponent, m_Colors, m_Columns);
        memcpy(m_pLastLine, m_pScanline, m_PredictPitch);
      } else {
        FlateOutput(m_pFlate, m_pScanline, m_Pitch);
        TIFF_PredictLine(m_pScanline, m_PredictPitch, m_bpc, m_nComps,
                         m_OutputWidth);
      }
    } else {
      size_t bytes_to_go = m_Pitch;
      size_t read_leftover =
          m_LeftOver > bytes_to_go ? bytes_to_go : m_LeftOver;
      if (read_leftover) {
        memcpy(m_pScanline, m_pPredictBuffer + m_PredictPitch - m_LeftOver,
               read_leftover);
        m_LeftOver -= read_leftover;
        bytes_to_go -= read_leftover;
      }
      while (bytes_to_go) {
        if (m_Predictor == 2) {
          FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1);
          PNG_PredictLine(m_pPredictBuffer, m_pPredictRaw, m_pLastLine,
                          m_BitsPerComponent, m_Colors, m_Columns);
          memcpy(m_pLastLine, m_pPredictBuffer, m_PredictPitch);
        } else {
          FlateOutput(m_pFlate, m_pPredictBuffer, m_PredictPitch);
          TIFF_PredictLine(m_pPredictBuffer, m_PredictPitch, m_BitsPerComponent,
                           m_Colors, m_Columns);
        }
        size_t read_bytes =
            m_PredictPitch > bytes_to_go ? bytes_to_go : m_PredictPitch;
        memcpy(m_pScanline + m_Pitch - bytes_to_go, m_pPredictBuffer,
               read_bytes);
        m_LeftOver += m_PredictPitch - read_bytes;
        bytes_to_go -= read_bytes;
      }
    }
  } else {
    FlateOutput(m_pFlate, m_pScanline, m_Pitch);
  }
  return m_pScanline;
}

uint32_t CCodec_FlateScanlineDecoder::GetSrcOffset() {
  return FlateGetPossiblyTruncatedTotalIn(m_pFlate);
}

std::unique_ptr<CCodec_ScanlineDecoder> CCodec_FlateModule::CreateDecoder(
    const uint8_t* src_buf,
    uint32_t src_size,
    int width,
    int height,
    int nComps,
    int bpc,
    int predictor,
    int Colors,
    int BitsPerComponent,
    int Columns) {
  auto pDecoder = pdfium::MakeUnique<CCodec_FlateScanlineDecoder>();
  pDecoder->Create(src_buf, src_size, width, height, nComps, bpc, predictor,
                   Colors, BitsPerComponent, Columns);
  return std::move(pDecoder);
}

uint32_t CCodec_FlateModule::FlateOrLZWDecode(bool bLZW,
                                              const uint8_t* src_buf,
                                              uint32_t src_size,
                                              bool bEarlyChange,
                                              int predictor,
                                              int Colors,
                                              int BitsPerComponent,
                                              int Columns,
                                              uint32_t estimated_size,
                                              uint8_t** dest_buf,
                                              uint32_t* dest_size) {
  *dest_buf = nullptr;
  uint32_t offset = 0;
  int predictor_type = 0;
  if (predictor) {
    if (predictor >= 10)
      predictor_type = 2;
    else if (predictor == 2)
      predictor_type = 1;
  }
  if (bLZW) {
    auto decoder = pdfium::MakeUnique<CLZWDecoder>();
    *dest_size = 0xFFFFFFFF;
    offset = src_size;
    int err =
        decoder->Decode(nullptr, *dest_size, src_buf, offset, bEarlyChange);
    if (err || *dest_size == 0 || *dest_size + 1 < *dest_size)
      return FX_INVALID_OFFSET;

    decoder = pdfium::MakeUnique<CLZWDecoder>();
    *dest_buf = FX_Alloc(uint8_t, *dest_size + 1);
    (*dest_buf)[*dest_size] = '\0';
    decoder->Decode(*dest_buf, *dest_size, src_buf, offset, bEarlyChange);
  } else {
    FlateUncompress(src_buf, src_size, estimated_size, *dest_buf, *dest_size,
                    offset);
  }
  if (predictor_type == 0)
    return offset;

  bool ret = true;
  if (predictor_type == 2) {
    ret =
        PNG_Predictor(*dest_buf, *dest_size, Colors, BitsPerComponent, Columns);
  } else if (predictor_type == 1) {
    ret = TIFF_Predictor(*dest_buf, *dest_size, Colors, BitsPerComponent,
                         Columns);
  }
  return ret ? offset : FX_INVALID_OFFSET;
}

bool CCodec_FlateModule::Encode(const uint8_t* src_buf,
                                uint32_t src_size,
                                uint8_t** dest_buf,
                                uint32_t* dest_size) {
  *dest_size = src_size + src_size / 1000 + 12;
  *dest_buf = FX_Alloc(uint8_t, *dest_size);
  unsigned long temp_size = *dest_size;
  if (!FlateCompress(*dest_buf, &temp_size, src_buf, src_size))
    return false;

  *dest_size = (uint32_t)temp_size;
  return true;
}

bool CCodec_FlateModule::PngEncode(const uint8_t* src_buf,
                                   uint32_t src_size,
                                   uint8_t** dest_buf,
                                   uint32_t* dest_size) {
  uint8_t* pSrcBuf = FX_Alloc(uint8_t, src_size);
  memcpy(pSrcBuf, src_buf, src_size);
  PNG_PredictorEncode(&pSrcBuf, &src_size);
  bool ret = Encode(pSrcBuf, src_size, dest_buf, dest_size);
  FX_Free(pSrcBuf);
  return ret;
}
