// Copyright 2018 The PDFium Authors
// 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/bmp/cfx_bmpdecompressor.h"

#include <stdint.h>

#include <algorithm>
#include <limits>
#include <utility>

#include "core/fxcodec/bmp/cfx_bmpcontext.h"
#include "core/fxcodec/cfx_codec_memory.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/span_util.h"
#include "core/fxge/calculate_pitch.h"
#include "third_party/base/numerics/safe_math.h"

namespace fxcodec {

namespace {

#define BMP_PAL_ENCODE(a, r, g, b) \
  (((uint32_t)(a) << 24) | ((r) << 16) | ((g) << 8) | (b))

constexpr size_t kBmpCoreHeaderSize = 12;
constexpr size_t kBmpInfoHeaderSize = 40;

static_assert(sizeof(BmpCoreHeader) == kBmpCoreHeaderSize,
              "BmpCoreHeader has wrong size");
static_assert(sizeof(BmpInfoHeader) == kBmpInfoHeaderSize,
              "BmpInfoHeader has wrong size");

constexpr uint16_t kBmpSignature = 0x4D42;
constexpr uint8_t kRleMarker = 0;
constexpr uint8_t kRleEol = 0;
constexpr uint8_t kRleEoi = 1;
constexpr uint8_t kRleDelta = 2;
constexpr uint32_t kBmpRgb = 0L;
constexpr uint32_t kBmpRle8 = 1L;
constexpr uint32_t kBmpRle4 = 2L;
constexpr uint32_t kBmpBitfields = 3L;

// Limit of image dimension. Use the same limit as the JBIG2 codecs.
constexpr uint32_t kBmpMaxImageDimension = 65535;

uint8_t HalfRoundUp(uint8_t value) {
  uint16_t value16 = value;
  return static_cast<uint8_t>((value16 + 1) / 2);
}

}  // namespace

CFX_BmpDecompressor::CFX_BmpDecompressor(const CFX_BmpContext* context)
    : context_(context) {}

CFX_BmpDecompressor::~CFX_BmpDecompressor() = default;

void CFX_BmpDecompressor::ReadNextScanline() {
  uint32_t row = img_tb_flag_ ? row_num_ : (height_ - 1 - row_num_);
  context_->m_pDelegate->BmpReadScanline(row, out_row_buffer_);
  ++row_num_;
}

bool CFX_BmpDecompressor::GetDataPosition(uint32_t rcd_pos) {
  return context_->m_pDelegate->BmpInputImagePositionBuf(rcd_pos);
}

BmpDecoder::Status CFX_BmpDecompressor::ReadHeader() {
  if (decode_status_ == DecodeStatus::kHeader) {
    BmpDecoder::Status status = ReadBmpHeader();
    if (status != BmpDecoder::Status::kSuccess)
      return status;
  }

  if (decode_status_ != DecodeStatus::kPal)
    return BmpDecoder::Status::kSuccess;

  if (compress_flag_ == kBmpBitfields)
    return ReadBmpBitfields();

  return ReadBmpPalette();
}

BmpDecoder::Status CFX_BmpDecompressor::ReadBmpHeader() {
  BmpFileHeader bmp_header;
  if (!ReadAllOrNone(
          pdfium::as_writable_bytes(pdfium::make_span(&bmp_header, 1)))) {
    return BmpDecoder::Status::kContinue;
  }

  bmp_header.bfType =
      FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&bmp_header.bfType));
  data_offset_ = FXSYS_UINT32_GET_LSBFIRST(
      reinterpret_cast<uint8_t*>(&bmp_header.bfOffBits));
  data_size_ =
      FXSYS_UINT32_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&bmp_header.bfSize));
  if (bmp_header.bfType != kBmpSignature)
    return BmpDecoder::Status::kFail;

  size_t pos = input_buffer_->GetPosition();
  if (!ReadAllOrNone(
          pdfium::as_writable_bytes(pdfium::make_span(&img_ifh_size_, 1)))) {
    return BmpDecoder::Status::kContinue;
  }
  if (!input_buffer_->Seek(pos))
    return BmpDecoder::Status::kFail;

  img_ifh_size_ =
      FXSYS_UINT32_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_ifh_size_));
  pal_type_ = PalType::kNew;
  BmpDecoder::Status status = ReadBmpHeaderIfh();
  if (status != BmpDecoder::Status::kSuccess)
    return status;

  return ReadBmpHeaderDimensions();
}

BmpDecoder::Status CFX_BmpDecompressor::ReadBmpHeaderIfh() {
  if (img_ifh_size_ == kBmpCoreHeaderSize) {
    pal_type_ = PalType::kOld;
    BmpCoreHeader bmp_core_header;
    if (!ReadAllOrNone(pdfium::as_writable_bytes(
            pdfium::make_span(&bmp_core_header, 1)))) {
      return BmpDecoder::Status::kContinue;
    }

    width_ = FXSYS_UINT16_GET_LSBFIRST(
        reinterpret_cast<uint8_t*>(&bmp_core_header.bcWidth));
    height_ = FXSYS_UINT16_GET_LSBFIRST(
        reinterpret_cast<uint8_t*>(&bmp_core_header.bcHeight));
    bit_counts_ = FXSYS_UINT16_GET_LSBFIRST(
        reinterpret_cast<uint8_t*>(&bmp_core_header.bcBitCount));
    compress_flag_ = kBmpRgb;
    img_tb_flag_ = false;
    return BmpDecoder::Status::kSuccess;
  }

  if (img_ifh_size_ == kBmpInfoHeaderSize) {
    BmpInfoHeader bmp_info_header;
    if (!ReadAllOrNone(pdfium::as_writable_bytes(
            pdfium::make_span(&bmp_info_header, 1)))) {
      return BmpDecoder::Status::kContinue;
    }

    width_ = FXSYS_UINT32_GET_LSBFIRST(
        reinterpret_cast<uint8_t*>(&bmp_info_header.biWidth));
    int32_t signed_height = FXSYS_UINT32_GET_LSBFIRST(
        reinterpret_cast<uint8_t*>(&bmp_info_header.biHeight));
    bit_counts_ = FXSYS_UINT16_GET_LSBFIRST(
        reinterpret_cast<uint8_t*>(&bmp_info_header.biBitCount));
    compress_flag_ = FXSYS_UINT32_GET_LSBFIRST(
        reinterpret_cast<uint8_t*>(&bmp_info_header.biCompression));
    color_used_ = FXSYS_UINT32_GET_LSBFIRST(
        reinterpret_cast<uint8_t*>(&bmp_info_header.biClrUsed));
    dpi_x_ = static_cast<int32_t>(FXSYS_UINT32_GET_LSBFIRST(
        reinterpret_cast<uint8_t*>(&bmp_info_header.biXPelsPerMeter)));
    dpi_y_ = static_cast<int32_t>(FXSYS_UINT32_GET_LSBFIRST(
        reinterpret_cast<uint8_t*>(&bmp_info_header.biYPelsPerMeter)));
    if (!SetHeight(signed_height))
      return BmpDecoder::Status::kFail;
    return BmpDecoder::Status::kSuccess;
  }

  if (img_ifh_size_ <= sizeof(BmpInfoHeader))
    return BmpDecoder::Status::kFail;

  FX_SAFE_SIZE_T new_pos = input_buffer_->GetPosition();
  BmpInfoHeader bmp_info_header;
  if (!ReadAllOrNone(
          pdfium::as_writable_bytes(pdfium::make_span(&bmp_info_header, 1)))) {
    return BmpDecoder::Status::kContinue;
  }

  new_pos += img_ifh_size_;
  if (!new_pos.IsValid())
    return BmpDecoder::Status::kFail;

  if (!input_buffer_->Seek(new_pos.ValueOrDie()))
    return BmpDecoder::Status::kContinue;

  uint16_t bi_planes;
  width_ = FXSYS_UINT32_GET_LSBFIRST(
      reinterpret_cast<uint8_t*>(&bmp_info_header.biWidth));
  int32_t signed_height = FXSYS_UINT32_GET_LSBFIRST(
      reinterpret_cast<uint8_t*>(&bmp_info_header.biHeight));
  bit_counts_ = FXSYS_UINT16_GET_LSBFIRST(
      reinterpret_cast<uint8_t*>(&bmp_info_header.biBitCount));
  compress_flag_ = FXSYS_UINT32_GET_LSBFIRST(
      reinterpret_cast<uint8_t*>(&bmp_info_header.biCompression));
  color_used_ = FXSYS_UINT32_GET_LSBFIRST(
      reinterpret_cast<uint8_t*>(&bmp_info_header.biClrUsed));
  bi_planes = FXSYS_UINT16_GET_LSBFIRST(
      reinterpret_cast<uint8_t*>(&bmp_info_header.biPlanes));
  dpi_x_ = FXSYS_UINT32_GET_LSBFIRST(
      reinterpret_cast<uint8_t*>(&bmp_info_header.biXPelsPerMeter));
  dpi_y_ = FXSYS_UINT32_GET_LSBFIRST(
      reinterpret_cast<uint8_t*>(&bmp_info_header.biYPelsPerMeter));
  if (!SetHeight(signed_height))
    return BmpDecoder::Status::kFail;
  if (compress_flag_ != kBmpRgb || bi_planes != 1 || color_used_ != 0)
    return BmpDecoder::Status::kFail;
  return BmpDecoder::Status::kSuccess;
}

BmpDecoder::Status CFX_BmpDecompressor::ReadBmpHeaderDimensions() {
  if (width_ > kBmpMaxImageDimension || height_ > kBmpMaxImageDimension ||
      compress_flag_ > kBmpBitfields) {
    return BmpDecoder::Status::kFail;
  }

  switch (bit_counts_) {
    case 1:
    case 4:
    case 8:
    case 16:
    case 24: {
      if (color_used_ > 1U << bit_counts_)
        return BmpDecoder::Status::kFail;
      break;
    }
    case 32:
      break;
    default:
      return BmpDecoder::Status::kFail;
  }
  absl::optional<uint32_t> stride = fxge::CalculatePitch32(bit_counts_, width_);
  if (!stride.has_value())
    return BmpDecoder::Status::kFail;

  src_row_bytes_ = stride.value();
  switch (bit_counts_) {
    case 1:
    case 4:
    case 8:
      stride = fxge::CalculatePitch32(8, width_);
      if (!stride.has_value())
        return BmpDecoder::Status::kFail;
      out_row_bytes_ = stride.value();
      components_ = 1;
      break;
    case 16:
    case 24:
      stride = fxge::CalculatePitch32(24, width_);
      if (!stride.has_value())
        return BmpDecoder::Status::kFail;
      out_row_bytes_ = stride.value();
      components_ = 3;
      break;
    case 32:
      out_row_bytes_ = src_row_bytes_;
      components_ = 4;
      break;
  }
  out_row_buffer_.clear();

  if (out_row_bytes_ <= 0)
    return BmpDecoder::Status::kFail;

  out_row_buffer_.resize(out_row_bytes_);
  SaveDecodingStatus(DecodeStatus::kPal);
  return BmpDecoder::Status::kSuccess;
}

BmpDecoder::Status CFX_BmpDecompressor::ReadBmpBitfields() {
  if (bit_counts_ != 16 && bit_counts_ != 32)
    return BmpDecoder::Status::kFail;

  uint32_t masks[3];
  if (!ReadAllOrNone(pdfium::as_writable_bytes(pdfium::make_span(masks))))
    return BmpDecoder::Status::kContinue;

  mask_red_ = FXSYS_UINT32_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[0]));
  mask_green_ =
      FXSYS_UINT32_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[1]));
  mask_blue_ = FXSYS_UINT32_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[2]));
  if (mask_red_ & mask_green_ || mask_red_ & mask_blue_ ||
      mask_green_ & mask_blue_) {
    return BmpDecoder::Status::kFail;
  }
  header_offset_ = std::max(header_offset_, 26 + img_ifh_size_);
  SaveDecodingStatus(DecodeStatus::kDataPre);
  return BmpDecoder::Status::kSuccess;
}

BmpDecoder::Status CFX_BmpDecompressor::ReadBmpPalette() {
  if (bit_counts_ == 16) {
    mask_red_ = 0x7C00;
    mask_green_ = 0x03E0;
    mask_blue_ = 0x001F;
  }
  pal_num_ = 0;
  if (bit_counts_ < 16) {
    pal_num_ = 1 << bit_counts_;
    if (color_used_ != 0)
      pal_num_ = color_used_;
    size_t src_pal_size = pal_num_ * PaletteChannelCount();
    DataVector<uint8_t> src_pal(src_pal_size);
    uint8_t* src_pal_data = src_pal.data();
    if (!ReadAllOrNone(src_pal))
      return BmpDecoder::Status::kContinue;

    palette_.resize(pal_num_);
    int32_t src_pal_index = 0;
    if (pal_type_ == PalType::kOld) {
      while (src_pal_index < pal_num_) {
        palette_[src_pal_index++] = BMP_PAL_ENCODE(
            0x00, src_pal_data[2], src_pal_data[1], src_pal_data[0]);
        src_pal_data += 3;
      }
    } else {
      while (src_pal_index < pal_num_) {
        palette_[src_pal_index++] = BMP_PAL_ENCODE(
            src_pal_data[3], src_pal_data[2], src_pal_data[1], src_pal_data[0]);
        src_pal_data += 4;
      }
    }
  }
  header_offset_ = std::max(
      header_offset_, 14 + img_ifh_size_ + pal_num_ * PaletteChannelCount());
  SaveDecodingStatus(DecodeStatus::kDataPre);
  return BmpDecoder::Status::kSuccess;
}

bool CFX_BmpDecompressor::ValidateFlag() const {
  switch (compress_flag_) {
    case kBmpRgb:
    case kBmpBitfields:
    case kBmpRle8:
    case kBmpRle4:
      return true;
    default:
      return false;
  }
}

BmpDecoder::Status CFX_BmpDecompressor::DecodeImage() {
  if (decode_status_ == DecodeStatus::kDataPre) {
    // In order to tolerate certain corrupt BMP files, use the header offset if
    // the data offset would point into the header.
    data_offset_ = std::max(header_offset_, data_offset_);

    input_buffer_->Seek(input_buffer_->GetSize());
    if (!GetDataPosition(data_offset_)) {
      decode_status_ = DecodeStatus::kTail;
      return BmpDecoder::Status::kFail;
    }

    row_num_ = 0;
    SaveDecodingStatus(DecodeStatus::kData);
  }
  if (decode_status_ != DecodeStatus::kData || !ValidateFlag())
    return BmpDecoder::Status::kFail;

  switch (compress_flag_) {
    case kBmpRgb:
    case kBmpBitfields:
      return DecodeRGB();
    case kBmpRle8:
      return DecodeRLE8();
    case kBmpRle4:
      return DecodeRLE4();
    default:
      return BmpDecoder::Status::kFail;
  }
}

bool CFX_BmpDecompressor::ValidateColorIndex(uint8_t val) const {
  return val < pal_num_;
}

BmpDecoder::Status CFX_BmpDecompressor::DecodeRGB() {
  DataVector<uint8_t> dest_buf(src_row_bytes_);
  while (row_num_ < height_) {
    size_t idx = 0;
    if (!ReadAllOrNone(dest_buf))
      return BmpDecoder::Status::kContinue;

    SaveDecodingStatus(DecodeStatus::kData);
    switch (bit_counts_) {
      case 1: {
        for (uint32_t col = 0; col < width_; ++col) {
          uint8_t index =
              dest_buf[col >> 3] & (0x80 >> (col % 8)) ? 0x01 : 0x00;
          if (!ValidateColorIndex(index))
            return BmpDecoder::Status::kFail;
          out_row_buffer_[idx++] = index;
        }
        break;
      }
      case 4: {
        for (uint32_t col = 0; col < width_; ++col) {
          uint8_t index = (col & 0x01) ? (dest_buf[col >> 1] & 0x0F)
                                       : ((dest_buf[col >> 1] & 0xF0) >> 4);
          if (!ValidateColorIndex(index))
            return BmpDecoder::Status::kFail;
          out_row_buffer_[idx++] = index;
        }
        break;
      }
      case 8: {
        for (uint32_t col = 0; col < width_; ++col) {
          uint8_t index = dest_buf[col];
          if (!ValidateColorIndex(index))
            return BmpDecoder::Status::kFail;
          out_row_buffer_[idx++] = index;
        }
        break;
      }
      case 16: {
        uint16_t* buf = reinterpret_cast<uint16_t*>(dest_buf.data());
        uint8_t blue_bits = 0;
        uint8_t green_bits = 0;
        uint8_t red_bits = 0;
        for (int32_t i = 0; i < 16; i++) {
          if ((mask_blue_ >> i) & 0x01)
            blue_bits++;
          if ((mask_green_ >> i) & 0x01)
            green_bits++;
          if ((mask_red_ >> i) & 0x01)
            red_bits++;
        }
        green_bits += blue_bits;
        red_bits += green_bits;
        if (blue_bits > 8 || green_bits < 8 || red_bits < 8)
          return BmpDecoder::Status::kContinue;
        blue_bits = 8 - blue_bits;
        green_bits -= 8;
        red_bits -= 8;
        for (uint32_t col = 0; col < width_; ++col) {
          *buf = FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<uint8_t*>(buf));
          out_row_buffer_[idx++] =
              static_cast<uint8_t>((*buf & mask_blue_) << blue_bits);
          out_row_buffer_[idx++] =
              static_cast<uint8_t>((*buf & mask_green_) >> green_bits);
          out_row_buffer_[idx++] =
              static_cast<uint8_t>((*buf++ & mask_red_) >> red_bits);
        }
        break;
      }
      case 24:
      case 32:
        // TODO(crbug.com/pdfium/1901): Apply bitfields.
        fxcrt::spancpy(pdfium::make_span(out_row_buffer_),
                       pdfium::make_span(dest_buf).first(src_row_bytes_));
        idx += src_row_bytes_;
        break;
    }
    ReadNextScanline();
  }
  SaveDecodingStatus(DecodeStatus::kTail);
  return BmpDecoder::Status::kSuccess;
}

BmpDecoder::Status CFX_BmpDecompressor::DecodeRLE8() {
  uint8_t first_part;
  col_num_ = 0;
  while (true) {
    if (!ReadAllOrNone(pdfium::make_span(&first_part, 1)))
      return BmpDecoder::Status::kContinue;

    switch (first_part) {
      case kRleMarker: {
        if (!ReadAllOrNone(pdfium::make_span(&first_part, 1)))
          return BmpDecoder::Status::kContinue;

        switch (first_part) {
          case kRleEol: {
            if (row_num_ >= height_) {
              SaveDecodingStatus(DecodeStatus::kTail);
              return BmpDecoder::Status::kFail;
            }

            ReadNextScanline();
            col_num_ = 0;
            fxcrt::spanset(pdfium::make_span(out_row_buffer_), 0);
            SaveDecodingStatus(DecodeStatus::kData);
            continue;
          }
          case kRleEoi: {
            if (row_num_ < height_)
              ReadNextScanline();
            SaveDecodingStatus(DecodeStatus::kTail);
            return BmpDecoder::Status::kSuccess;
          }
          case kRleDelta: {
            uint8_t delta[2];
            if (!ReadAllOrNone(delta))
              return BmpDecoder::Status::kContinue;

            col_num_ += delta[0];
            size_t bmp_row_num__next = row_num_ + delta[1];
            if (col_num_ >= out_row_bytes_ || bmp_row_num__next >= height_)
              return BmpDecoder::Status::kFail;

            while (row_num_ < bmp_row_num__next) {
              fxcrt::spanset(pdfium::make_span(out_row_buffer_), 0);
              ReadNextScanline();
            }
            break;
          }
          default: {
            int32_t avail_size =
                pdfium::base::checked_cast<int32_t>(out_row_bytes_ - col_num_);
            if (!avail_size || static_cast<int32_t>(first_part) > avail_size)
              return BmpDecoder::Status::kFail;

            size_t second_part_size =
                first_part & 1 ? first_part + 1 : first_part;
            DataVector<uint8_t> second_part(second_part_size);
            if (!ReadAllOrNone(second_part))
              return BmpDecoder::Status::kContinue;

            fxcrt::spancpy(pdfium::make_span(out_row_buffer_).subspan(col_num_),
                           pdfium::make_span(second_part).first(first_part));

            for (size_t i = col_num_; i < col_num_ + first_part; ++i) {
              if (!ValidateColorIndex(out_row_buffer_[i]))
                return BmpDecoder::Status::kFail;
            }
            col_num_ += first_part;
          }
        }
        break;
      }
      default: {
        int32_t avail_size =
            pdfium::base::checked_cast<int32_t>(out_row_bytes_ - col_num_);
        if (!avail_size || static_cast<int32_t>(first_part) > avail_size)
          return BmpDecoder::Status::kFail;

        uint8_t second_part;
        if (!ReadAllOrNone(pdfium::make_span(&second_part, 1)))
          return BmpDecoder::Status::kContinue;

        fxcrt::spanset(
            pdfium::make_span(out_row_buffer_).subspan(col_num_, first_part),
            second_part);

        if (!ValidateColorIndex(out_row_buffer_[col_num_]))
          return BmpDecoder::Status::kFail;
        col_num_ += first_part;
      }
    }
  }
}

BmpDecoder::Status CFX_BmpDecompressor::DecodeRLE4() {
  uint8_t first_part;
  col_num_ = 0;
  while (true) {
    if (!ReadAllOrNone(pdfium::make_span(&first_part, 1)))
      return BmpDecoder::Status::kContinue;

    switch (first_part) {
      case kRleMarker: {
        if (!ReadAllOrNone(pdfium::make_span(&first_part, 1)))
          return BmpDecoder::Status::kContinue;

        switch (first_part) {
          case kRleEol: {
            if (row_num_ >= height_) {
              SaveDecodingStatus(DecodeStatus::kTail);
              return BmpDecoder::Status::kFail;
            }

            ReadNextScanline();
            col_num_ = 0;
            fxcrt::spanset(pdfium::make_span(out_row_buffer_), 0);
            SaveDecodingStatus(DecodeStatus::kData);
            continue;
          }
          case kRleEoi: {
            if (row_num_ < height_)
              ReadNextScanline();
            SaveDecodingStatus(DecodeStatus::kTail);
            return BmpDecoder::Status::kSuccess;
          }
          case kRleDelta: {
            uint8_t delta[2];
            if (!ReadAllOrNone(delta))
              return BmpDecoder::Status::kContinue;

            col_num_ += delta[0];
            size_t bmp_row_num__next = row_num_ + delta[1];
            if (col_num_ >= out_row_bytes_ || bmp_row_num__next >= height_)
              return BmpDecoder::Status::kFail;

            while (row_num_ < bmp_row_num__next) {
              fxcrt::spanset(pdfium::make_span(out_row_buffer_), 0);
              ReadNextScanline();
            }
            break;
          }
          default: {
            int32_t avail_size =
                pdfium::base::checked_cast<int32_t>(out_row_bytes_ - col_num_);
            if (!avail_size)
              return BmpDecoder::Status::kFail;
            uint8_t size = HalfRoundUp(first_part);
            if (static_cast<int32_t>(first_part) > avail_size) {
              if (size + (col_num_ >> 1) > src_row_bytes_)
                return BmpDecoder::Status::kFail;

              first_part = avail_size - 1;
            }
            size_t second_part_size = size & 1 ? size + 1 : size;
            DataVector<uint8_t> second_part(second_part_size);
            uint8_t* second_part_data = second_part.data();
            if (!ReadAllOrNone(second_part))
              return BmpDecoder::Status::kContinue;

            for (uint8_t i = 0; i < first_part; i++) {
              uint8_t color = (i & 0x01) ? (*second_part_data++ & 0x0F)
                                         : (*second_part_data & 0xF0) >> 4;
              if (!ValidateColorIndex(color))
                return BmpDecoder::Status::kFail;

              out_row_buffer_[col_num_++] = color;
            }
          }
        }
        break;
      }
      default: {
        int32_t avail_size =
            pdfium::base::checked_cast<int32_t>(out_row_bytes_ - col_num_);
        if (!avail_size)
          return BmpDecoder::Status::kFail;

        if (static_cast<int32_t>(first_part) > avail_size) {
          uint8_t size = HalfRoundUp(first_part);
          if (size + (col_num_ >> 1) > src_row_bytes_)
            return BmpDecoder::Status::kFail;

          first_part = avail_size - 1;
        }
        uint8_t second_part;
        if (!ReadAllOrNone(pdfium::make_span(&second_part, 1)))
          return BmpDecoder::Status::kContinue;

        for (uint8_t i = 0; i < first_part; i++) {
          uint8_t second_byte = second_part;
          second_byte =
              i & 0x01 ? (second_byte & 0x0F) : (second_byte & 0xF0) >> 4;
          if (!ValidateColorIndex(second_byte))
            return BmpDecoder::Status::kFail;

          out_row_buffer_[col_num_++] = second_byte;
        }
      }
    }
  }
}

bool CFX_BmpDecompressor::ReadAllOrNone(pdfium::span<uint8_t> buf) {
  if (!input_buffer_)
    return false;

  size_t original_position = input_buffer_->GetPosition();
  size_t read = input_buffer_->ReadBlock(buf);
  if (read < buf.size()) {
    input_buffer_->Seek(original_position);
    return false;
  }

  return true;
}

void CFX_BmpDecompressor::SaveDecodingStatus(DecodeStatus status) {
  decode_status_ = status;
}

void CFX_BmpDecompressor::SetInputBuffer(
    RetainPtr<CFX_CodecMemory> codec_memory) {
  input_buffer_ = std::move(codec_memory);
}

FX_FILESIZE CFX_BmpDecompressor::GetAvailInput() const {
  if (!input_buffer_)
    return 0;

  return input_buffer_->GetSize() - input_buffer_->GetPosition();
}

bool CFX_BmpDecompressor::SetHeight(int32_t signed_height) {
  if (signed_height >= 0) {
    height_ = signed_height;
    return true;
  }
  if (signed_height != std::numeric_limits<int>::min()) {
    height_ = -signed_height;
    img_tb_flag_ = true;
    return true;
  }
  return false;
}

}  // namespace fxcodec
