// Copyright 2014 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/jbig2/JBig2_Context.h"

#include <algorithm>
#include <array>
#include <limits>
#include <list>
#include <utility>
#include <vector>

#include "core/fxcodec/jbig2/JBig2_ArithDecoder.h"
#include "core/fxcodec/jbig2/JBig2_BitStream.h"
#include "core/fxcodec/jbig2/JBig2_GrdProc.h"
#include "core/fxcodec/jbig2/JBig2_GrrdProc.h"
#include "core/fxcodec/jbig2/JBig2_HtrdProc.h"
#include "core/fxcodec/jbig2/JBig2_PddProc.h"
#include "core/fxcodec/jbig2/JBig2_SddProc.h"
#include "core/fxcodec/jbig2/JBig2_TrdProc.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/fixed_size_data_vector.h"
#include "core/fxcrt/fx_memory_wrappers.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/pauseindicator_iface.h"
#include "core/fxcrt/ptr_util.h"

namespace {

size_t GetHuffContextSize(uint8_t val) {
  return val == 0 ? 65536 : val == 1 ? 8192 : 1024;
}

size_t GetRefAggContextSize(bool val) {
  return val ? 1024 : 8192;
}

}  // namespace

// Implement a very small least recently used (LRU) cache. It is very
// common for a JBIG2 dictionary to span multiple pages in a PDF file,
// and we do not want to decode the same dictionary over and over
// again. We key off of the memory location of the dictionary. The
// list keeps track of the freshness of entries, with freshest ones
// at the front. Even a tiny cache size like 2 makes a dramatic
// difference for typical JBIG2 documents.
static const size_t kSymbolDictCacheMaxSize = 2;
static_assert(kSymbolDictCacheMaxSize > 0,
              "Symbol Dictionary Cache must have non-zero size");

// static
std::unique_ptr<CJBig2_Context> CJBig2_Context::Create(
    pdfium::span<const uint8_t> pGlobalSpan,
    uint64_t global_key,
    pdfium::span<const uint8_t> pSrcSpan,
    uint64_t src_key,
    std::list<CJBig2_CachePair>* pSymbolDictCache) {
  auto result = pdfium::WrapUnique(
      new CJBig2_Context(pSrcSpan, src_key, pSymbolDictCache, false));
  if (!pGlobalSpan.empty()) {
    result->global_context_ = pdfium::WrapUnique(
        new CJBig2_Context(pGlobalSpan, global_key, pSymbolDictCache, true));
  }
  return result;
}

CJBig2_Context::CJBig2_Context(pdfium::span<const uint8_t> pSrcSpan,
                               uint64_t src_key,
                               std::list<CJBig2_CachePair>* pSymbolDictCache,
                               bool bIsGlobal)
    : stream_(std::make_unique<CJBig2_BitStream>(pSrcSpan, src_key)),
      huffman_tables_(CJBig2_HuffmanTable::kNumHuffmanTables),
      is_global_(bIsGlobal),
      symbol_dict_cache_(pSymbolDictCache) {}

CJBig2_Context::~CJBig2_Context() = default;

JBig2_Result CJBig2_Context::DecodeSequential(PauseIndicatorIface* pPause) {
  if (stream_->getByteLeft() <= 0) {
    return JBig2_Result::kEndReached;
  }

  while (stream_->getByteLeft() >= JBIG2_MIN_SEGMENT_SIZE) {
    JBig2_Result nRet;
    if (!segment_) {
      segment_ = std::make_unique<CJBig2_Segment>();
      nRet = ParseSegmentHeader(segment_.get());
      if (nRet != JBig2_Result::kSuccess) {
        segment_.reset();
        return nRet;
      }
      offset_ = stream_->getOffset();
    }
    nRet = ParseSegmentData(segment_.get(), pPause);
    if (processing_status_ == FXCODEC_STATUS::kDecodeToBeContinued) {
      pause_step_ = 2;
      return JBig2_Result::kSuccess;
    }
    if (nRet == JBig2_Result::kEndReached) {
      segment_.reset();
      return JBig2_Result::kSuccess;
    }
    if (nRet != JBig2_Result::kSuccess) {
      segment_.reset();
      return nRet;
    }
    if (segment_->data_length_ != 0xffffffff) {
      FX_SAFE_UINT32 new_offset = offset_;
      new_offset += segment_->data_length_;
      if (!new_offset.IsValid()) {
        return JBig2_Result::kFailure;
      }
      offset_ = new_offset.ValueOrDie();
      stream_->setOffset(offset_);
    } else {
      stream_->addOffset(4);
    }
    segment_list_.push_back(std::move(segment_));
    if (stream_->getByteLeft() > 0 && page_ && pPause &&
        pPause->NeedToPauseNow()) {
      processing_status_ = FXCODEC_STATUS::kDecodeToBeContinued;
      pause_step_ = 2;
      return JBig2_Result::kSuccess;
    }
  }
  return JBig2_Result::kSuccess;
}

bool CJBig2_Context::GetFirstPage(pdfium::span<uint8_t> pBuf,
                                  int32_t width,
                                  int32_t height,
                                  int32_t stride,
                                  PauseIndicatorIface* pPause) {
  if (global_context_) {
    JBig2_Result nRet = global_context_->DecodeSequential(pPause);
    if (nRet != JBig2_Result::kSuccess) {
      processing_status_ = FXCODEC_STATUS::kError;
      return nRet == JBig2_Result::kSuccess;
    }
  }
  pause_step_ = 0;
  page_ = std::make_unique<CJBig2_Image>(width, height, stride, pBuf);
  buf_specified_ = true;
  if (pPause && pPause->NeedToPauseNow()) {
    pause_step_ = 1;
    processing_status_ = FXCODEC_STATUS::kDecodeToBeContinued;
    return true;
  }
  return Continue(pPause);
}

bool CJBig2_Context::Continue(PauseIndicatorIface* pPause) {
  processing_status_ = FXCODEC_STATUS::kDecodeReady;
  JBig2_Result nRet = JBig2_Result::kSuccess;
  if (pause_step_ == 5) {
    processing_status_ = FXCODEC_STATUS::kDecodeFinished;
    return true;
  }

  if (pause_step_ <= 2) {
    nRet = DecodeSequential(pPause);
  }
  if (processing_status_ == FXCODEC_STATUS::kDecodeToBeContinued) {
    return nRet == JBig2_Result::kSuccess;
  }

  pause_step_ = 5;
  if (!buf_specified_ && nRet == JBig2_Result::kSuccess) {
    processing_status_ = FXCODEC_STATUS::kDecodeFinished;
    return true;
  }
  processing_status_ = nRet == JBig2_Result::kSuccess
                           ? FXCODEC_STATUS::kDecodeFinished
                           : FXCODEC_STATUS::kError;
  return nRet == JBig2_Result::kSuccess;
}

CJBig2_Segment* CJBig2_Context::FindSegmentByNumber(uint32_t dwNumber) {
  if (global_context_) {
    CJBig2_Segment* pSeg = global_context_->FindSegmentByNumber(dwNumber);
    if (pSeg) {
      return pSeg;
    }
  }
  for (const auto& pSeg : segment_list_) {
    if (pSeg->number_ == dwNumber) {
      return pSeg.get();
    }
  }
  return nullptr;
}

CJBig2_Segment* CJBig2_Context::FindReferredTableSegmentByIndex(
    CJBig2_Segment* pSegment,
    int32_t nIndex) {
  static const uint8_t kTableType = 53;
  int32_t count = 0;
  for (int32_t i = 0; i < pSegment->referred_to_segment_count_; ++i) {
    CJBig2_Segment* pSeg =
        FindSegmentByNumber(pSegment->referred_to_segment_numbers_[i]);
    if (pSeg && pSeg->flags_.s.type == kTableType) {
      if (count == nIndex) {
        return pSeg;
      }
      ++count;
    }
  }
  return nullptr;
}

JBig2_Result CJBig2_Context::ParseSegmentHeader(CJBig2_Segment* pSegment) {
  if (stream_->readInteger(&pSegment->number_) != 0 ||
      stream_->read1Byte(&pSegment->flags_.c) != 0) {
    return JBig2_Result::kFailure;
  }

  uint8_t cTemp = stream_->getCurByte();
  if ((cTemp >> 5) == 7) {
    if (stream_->readInteger(
            (uint32_t*)&pSegment->referred_to_segment_count_) != 0) {
      return JBig2_Result::kFailure;
    }
    pSegment->referred_to_segment_count_ &= 0x1fffffff;
    if (pSegment->referred_to_segment_count_ > kJBig2MaxReferredSegmentCount) {
      return JBig2_Result::kFailure;
    }
  } else {
    if (stream_->read1Byte(&cTemp) != 0) {
      return JBig2_Result::kFailure;
    }

    pSegment->referred_to_segment_count_ = cTemp >> 5;
  }
  uint8_t cSSize = pSegment->number_ > 65536 ? 4
                   : pSegment->number_ > 256 ? 2
                                             : 1;
  uint8_t cPSize = pSegment->flags_.s.page_association_size ? 4 : 1;
  if (pSegment->referred_to_segment_count_) {
    pSegment->referred_to_segment_numbers_.resize(
        pSegment->referred_to_segment_count_);
    for (int32_t i = 0; i < pSegment->referred_to_segment_count_; ++i) {
      switch (cSSize) {
        case 1:
          if (stream_->read1Byte(&cTemp) != 0) {
            return JBig2_Result::kFailure;
          }

          pSegment->referred_to_segment_numbers_[i] = cTemp;
          break;
        case 2:
          uint16_t wTemp;
          if (stream_->readShortInteger(&wTemp) != 0) {
            return JBig2_Result::kFailure;
          }

          pSegment->referred_to_segment_numbers_[i] = wTemp;
          break;
        case 4:
          uint32_t dwTemp;
          if (stream_->readInteger(&dwTemp) != 0) {
            return JBig2_Result::kFailure;
          }

          pSegment->referred_to_segment_numbers_[i] = dwTemp;
          break;
      }
      if (pSegment->referred_to_segment_numbers_[i] >= pSegment->number_) {
        return JBig2_Result::kFailure;
      }
    }
  }
  if (cPSize == 1) {
    if (stream_->read1Byte(&cTemp) != 0) {
      return JBig2_Result::kFailure;
    }
    pSegment->page_association_ = cTemp;
  } else if (stream_->readInteger(&pSegment->page_association_) != 0) {
    return JBig2_Result::kFailure;
  }
  if (stream_->readInteger(&pSegment->data_length_) != 0) {
    return JBig2_Result::kFailure;
  }

  pSegment->key_ = stream_->getKey();
  pSegment->data_offset_ = stream_->getOffset();
  pSegment->state_ = JBIG2_SEGMENT_DATA_UNPARSED;
  return JBig2_Result::kSuccess;
}

JBig2_Result CJBig2_Context::ParseSegmentData(CJBig2_Segment* pSegment,
                                              PauseIndicatorIface* pPause) {
  JBig2_Result ret = ProcessingParseSegmentData(pSegment, pPause);
  while (processing_status_ == FXCODEC_STATUS::kDecodeToBeContinued &&
         stream_->getByteLeft() > 0) {
    ret = ProcessingParseSegmentData(pSegment, pPause);
  }
  return ret;
}

JBig2_Result CJBig2_Context::ProcessingParseSegmentData(
    CJBig2_Segment* pSegment,
    PauseIndicatorIface* pPause) {
  switch (pSegment->flags_.s.type) {
    case 0:
      return ParseSymbolDict(pSegment);
    case 4:
    case 6:
    case 7:
      if (!in_page_) {
        return JBig2_Result::kFailure;
      }
      return ParseTextRegion(pSegment);
    case 16:
      return ParsePatternDict(pSegment, pPause);
    case 20:
    case 22:
    case 23:
      if (!in_page_) {
        return JBig2_Result::kFailure;
      }
      return ParseHalftoneRegion(pSegment, pPause);
    case 36:
    case 38:
    case 39:
      if (!in_page_) {
        return JBig2_Result::kFailure;
      }
      return ParseGenericRegion(pSegment, pPause);
    case 40:
    case 42:
    case 43:
      if (!in_page_) {
        return JBig2_Result::kFailure;
      }
      return ParseGenericRefinementRegion(pSegment);
    case 48: {
      uint8_t segment_flags;
      uint16_t striping_info;
      auto pPageInfo = std::make_unique<JBig2PageInfo>();
      if (stream_->readInteger(&pPageInfo->width_) != 0 ||
          stream_->readInteger(&pPageInfo->height_) != 0 ||
          stream_->readInteger(&pPageInfo->resolution_x_) != 0 ||
          stream_->readInteger(&pPageInfo->resolution_y_) != 0 ||
          stream_->read1Byte(&segment_flags) != 0 ||
          stream_->readShortInteger(&striping_info) != 0) {
        return JBig2_Result::kFailure;
      }

      pPageInfo->default_pixel_value_ = !!(segment_flags & 4);
      pPageInfo->is_striped_ = !!(striping_info & 0x8000);
      pPageInfo->max_stripe_size_ = striping_info & 0x7fff;
      bool bMaxHeight = (pPageInfo->height_ == 0xffffffff);
      if (bMaxHeight && !pPageInfo->is_striped_) {
        pPageInfo->is_striped_ = true;
      }

      if (!buf_specified_) {
        uint32_t height =
            bMaxHeight ? pPageInfo->max_stripe_size_ : pPageInfo->height_;
        page_ = std::make_unique<CJBig2_Image>(pPageInfo->width_, height);
      }

      if (!page_->data()) {
        processing_status_ = FXCODEC_STATUS::kError;
        return JBig2_Result::kFailure;
      }

      page_->Fill(pPageInfo->default_pixel_value_);
      page_info_list_.push_back(std::move(pPageInfo));
      in_page_ = true;
      break;
    }
    case 49:
      in_page_ = false;
      return JBig2_Result::kEndReached;
    case 50:
      stream_->addOffset(pSegment->data_length_);
      break;
    case 51:
      return JBig2_Result::kEndReached;
    case 52:
      stream_->addOffset(pSegment->data_length_);
      break;
    case 53:
      return ParseTable(pSegment);
    case 62:
      stream_->addOffset(pSegment->data_length_);
      break;
    default:
      break;
  }
  return JBig2_Result::kSuccess;
}

JBig2_Result CJBig2_Context::ParseSymbolDict(CJBig2_Segment* pSegment) {
  uint16_t wFlags;
  if (stream_->readShortInteger(&wFlags) != 0) {
    return JBig2_Result::kFailure;
  }

  auto pSymbolDictDecoder = std::make_unique<CJBig2_SDDProc>();
  pSymbolDictDecoder->SDHUFF = wFlags & 0x0001;
  pSymbolDictDecoder->SDREFAGG = (wFlags >> 1) & 0x0001;
  pSymbolDictDecoder->SDTEMPLATE = (wFlags >> 10) & 0x0003;
  pSymbolDictDecoder->SDRTEMPLATE = !!((wFlags >> 12) & 0x0003);
  if (!pSymbolDictDecoder->SDHUFF) {
    const uint32_t dwTemp = (pSymbolDictDecoder->SDTEMPLATE == 0) ? 8 : 2;
    for (uint32_t i = 0; i < dwTemp; ++i) {
      if (stream_->read1Byte((uint8_t*)&pSymbolDictDecoder->SDAT[i]) != 0) {
        return JBig2_Result::kFailure;
      }
    }
  }
  if (pSymbolDictDecoder->SDREFAGG && !pSymbolDictDecoder->SDRTEMPLATE) {
    for (int32_t i = 0; i < 4; ++i) {
      if (stream_->read1Byte((uint8_t*)&pSymbolDictDecoder->SDRAT[i]) != 0) {
        return JBig2_Result::kFailure;
      }
    }
  }
  if (stream_->readInteger(&pSymbolDictDecoder->SDNUMEXSYMS) != 0 ||
      stream_->readInteger(&pSymbolDictDecoder->SDNUMNEWSYMS) != 0) {
    return JBig2_Result::kFailure;
  }
  if (pSymbolDictDecoder->SDNUMEXSYMS > kJBig2MaxExportSymbols ||
      pSymbolDictDecoder->SDNUMNEWSYMS > kJBig2MaxNewSymbols) {
    return JBig2_Result::kFailure;
  }
  for (int32_t i = 0; i < pSegment->referred_to_segment_count_; ++i) {
    if (!FindSegmentByNumber(pSegment->referred_to_segment_numbers_[i])) {
      return JBig2_Result::kFailure;
    }
  }
  CJBig2_Segment* pLRSeg = nullptr;
  FX_SAFE_UINT32 dwNumSyms = 0;
  for (int32_t i = 0; i < pSegment->referred_to_segment_count_; ++i) {
    CJBig2_Segment* pSeg =
        FindSegmentByNumber(pSegment->referred_to_segment_numbers_[i]);
    if (pSeg->flags_.s.type == 0) {
      dwNumSyms += pSeg->symbol_dict_->NumImages();
      pLRSeg = pSeg;
    }
  }
  pSymbolDictDecoder->SDNUMINSYMS = dwNumSyms.ValueOrDie();

  std::vector<UnownedPtr<CJBig2_Image>> SDINSYMS(
      pSymbolDictDecoder->SDNUMINSYMS);
  if (!SDINSYMS.empty()) {
    dwNumSyms = 0;
    for (int32_t i = 0; i < pSegment->referred_to_segment_count_; ++i) {
      CJBig2_Segment* pSeg =
          FindSegmentByNumber(pSegment->referred_to_segment_numbers_[i]);
      if (pSeg->flags_.s.type == 0) {
        const CJBig2_SymbolDict& dict = *pSeg->symbol_dict_;
        for (uint32_t j = 0; j < dict.NumImages(); ++j) {
          uint32_t dwTemp = (dwNumSyms + j).ValueOrDie();
          SDINSYMS[dwTemp] = dict.GetImage(j);
        }
        dwNumSyms += dict.NumImages();
      }
    }
  }
  pSymbolDictDecoder->SDINSYMS = std::move(SDINSYMS);

  uint8_t cSDHUFFDH = (wFlags >> 2) & 0x0003;
  uint8_t cSDHUFFDW = (wFlags >> 4) & 0x0003;
  if (pSymbolDictDecoder->SDHUFF) {
    if (cSDHUFFDH == 2 || cSDHUFFDW == 2) {
      return JBig2_Result::kFailure;
    }

    int32_t nIndex = 0;
    if (cSDHUFFDH == 0) {
      pSymbolDictDecoder->SDHUFFDH = GetHuffmanTable(4);
    } else if (cSDHUFFDH == 1) {
      pSymbolDictDecoder->SDHUFFDH = GetHuffmanTable(5);
    } else {
      CJBig2_Segment* pSeg =
          FindReferredTableSegmentByIndex(pSegment, nIndex++);
      if (!pSeg) {
        return JBig2_Result::kFailure;
      }
      pSymbolDictDecoder->SDHUFFDH = pSeg->huffman_table_.get();
    }
    if (cSDHUFFDW == 0) {
      pSymbolDictDecoder->SDHUFFDW = GetHuffmanTable(2);
    } else if (cSDHUFFDW == 1) {
      pSymbolDictDecoder->SDHUFFDW = GetHuffmanTable(3);
    } else {
      CJBig2_Segment* pSeg =
          FindReferredTableSegmentByIndex(pSegment, nIndex++);
      if (!pSeg) {
        return JBig2_Result::kFailure;
      }
      pSymbolDictDecoder->SDHUFFDW = pSeg->huffman_table_.get();
    }
    uint8_t cSDHUFFBMSIZE = (wFlags >> 6) & 0x0001;
    if (cSDHUFFBMSIZE == 0) {
      pSymbolDictDecoder->SDHUFFBMSIZE = GetHuffmanTable(1);
    } else {
      CJBig2_Segment* pSeg =
          FindReferredTableSegmentByIndex(pSegment, nIndex++);
      if (!pSeg) {
        return JBig2_Result::kFailure;
      }
      pSymbolDictDecoder->SDHUFFBMSIZE = pSeg->huffman_table_.get();
    }
    if (pSymbolDictDecoder->SDREFAGG) {
      uint8_t cSDHUFFAGGINST = (wFlags >> 7) & 0x0001;
      if (cSDHUFFAGGINST == 0) {
        pSymbolDictDecoder->SDHUFFAGGINST = GetHuffmanTable(1);
      } else {
        CJBig2_Segment* pSeg =
            FindReferredTableSegmentByIndex(pSegment, nIndex++);
        if (!pSeg) {
          return JBig2_Result::kFailure;
        }
        pSymbolDictDecoder->SDHUFFAGGINST = pSeg->huffman_table_.get();
      }
    }
  }

  const bool bUseGbContext = !pSymbolDictDecoder->SDHUFF;
  const bool bUseGrContext = pSymbolDictDecoder->SDREFAGG;
  const size_t gbContextSize =
      GetHuffContextSize(pSymbolDictDecoder->SDTEMPLATE);
  const size_t grContextSize =
      GetRefAggContextSize(pSymbolDictDecoder->SDRTEMPLATE);
  std::vector<JBig2ArithCtx> gbContexts;
  std::vector<JBig2ArithCtx> grContexts;
  if ((wFlags & 0x0100) && pLRSeg) {
    if (bUseGbContext) {
      gbContexts = pLRSeg->symbol_dict_->GbContexts();
      if (gbContexts.size() != gbContextSize) {
        return JBig2_Result::kFailure;
      }
    }
    if (bUseGrContext) {
      grContexts = pLRSeg->symbol_dict_->GrContexts();
      if (grContexts.size() != grContextSize) {
        return JBig2_Result::kFailure;
      }
    }
  } else {
    if (bUseGbContext) {
      gbContexts.resize(gbContextSize);
    }
    if (bUseGrContext) {
      grContexts.resize(grContextSize);
    }
  }

  CJBig2_CompoundKey key(pSegment->key_, pSegment->data_offset_);
  bool cache_hit = false;
  pSegment->result_type_ = JBIG2_SYMBOL_DICT_POINTER;
  if (is_global_ && key.first != 0) {
    for (auto it = symbol_dict_cache_->begin(); it != symbol_dict_cache_->end();
         ++it) {
      if (it->first == key) {
        pSegment->symbol_dict_ = it->second->DeepCopy();
        symbol_dict_cache_->emplace_front(key, std::move(it->second));
        symbol_dict_cache_->erase(it);
        cache_hit = true;
        break;
      }
    }
  }
  if (!cache_hit) {
    if (bUseGbContext) {
      auto pArithDecoder = std::make_unique<CJBig2_ArithDecoder>(stream_.get());
      pSegment->symbol_dict_ = pSymbolDictDecoder->DecodeArith(
          pArithDecoder.get(), gbContexts, grContexts);
      if (!pSegment->symbol_dict_) {
        return JBig2_Result::kFailure;
      }

      stream_->alignByte();
      stream_->addOffset(2);
    } else {
      pSegment->symbol_dict_ = pSymbolDictDecoder->DecodeHuffman(
          stream_.get(), gbContexts, grContexts);
      if (!pSegment->symbol_dict_) {
        return JBig2_Result::kFailure;
      }
      stream_->alignByte();
    }
    if (is_global_) {
      std::unique_ptr<CJBig2_SymbolDict> value =
          pSegment->symbol_dict_->DeepCopy();
      size_t size = symbol_dict_cache_->size();
      while (size >= kSymbolDictCacheMaxSize) {
        symbol_dict_cache_->pop_back();
        --size;
      }
      symbol_dict_cache_->emplace_front(key, std::move(value));
    }
  }
  if (wFlags & 0x0200) {
    if (bUseGbContext) {
      pSegment->symbol_dict_->SetGbContexts(std::move(gbContexts));
    }
    if (bUseGrContext) {
      pSegment->symbol_dict_->SetGrContexts(std::move(grContexts));
    }
  }
  return JBig2_Result::kSuccess;
}

JBig2_Result CJBig2_Context::ParseTextRegion(CJBig2_Segment* pSegment) {
  uint16_t wFlags;
  JBig2RegionInfo ri;
  if (ParseRegionInfo(&ri) != JBig2_Result::kSuccess ||
      stream_->readShortInteger(&wFlags) != 0) {
    return JBig2_Result::kFailure;
  }
  if (!CJBig2_Image::IsValidImageSize(ri.width, ri.height)) {
    return JBig2_Result::kFailure;
  }

  auto pTRD = std::make_unique<CJBig2_TRDProc>();
  pTRD->SBW = ri.width;
  pTRD->SBH = ri.height;
  pTRD->SBHUFF = wFlags & 0x0001;
  pTRD->SBREFINE = (wFlags >> 1) & 0x0001;
  uint32_t dwTemp = (wFlags >> 2) & 0x0003;
  pTRD->SBSTRIPS = 1 << dwTemp;
  pTRD->REFCORNER = (JBig2Corner)((wFlags >> 4) & 0x0003);
  pTRD->TRANSPOSED = (wFlags >> 6) & 0x0001;
  pTRD->SBCOMBOP = (JBig2ComposeOp)((wFlags >> 7) & 0x0003);
  pTRD->SBDEFPIXEL = (wFlags >> 9) & 0x0001;
  pTRD->SBDSOFFSET = (wFlags >> 10) & 0x001f;
  if (pTRD->SBDSOFFSET >= 0x0010) {
    pTRD->SBDSOFFSET = pTRD->SBDSOFFSET - 0x0020;
  }
  pTRD->SBRTEMPLATE = !!((wFlags >> 15) & 0x0001);

  if (pTRD->SBHUFF && stream_->readShortInteger(&wFlags) != 0) {
    return JBig2_Result::kFailure;
  }
  if (pTRD->SBREFINE && !pTRD->SBRTEMPLATE) {
    for (int32_t i = 0; i < 4; ++i) {
      if (stream_->read1Byte((uint8_t*)&pTRD->SBRAT[i]) != 0) {
        return JBig2_Result::kFailure;
      }
    }
  }
  if (stream_->readInteger(&pTRD->SBNUMINSTANCES) != 0) {
    return JBig2_Result::kFailure;
  }

  // Assume each instance takes at least 0.25 bits when encoded. That means for
  // a stream of length N bytes, there can be at most 32N instances. This is a
  // conservative estimate just to sanitize the |SBNUMINSTANCES| value.
  // Use FX_SAFE_INT32 to be safe, though it should never overflow because PDFs
  // have a maximum size of roughly 11 GB.
  FX_SAFE_INT32 nMaxStripInstances = stream_->getBufSpan().size();
  nMaxStripInstances *= 32;
  if (pTRD->SBNUMINSTANCES > nMaxStripInstances.ValueOrDie()) {
    return JBig2_Result::kFailure;
  }

  for (int32_t i = 0; i < pSegment->referred_to_segment_count_; ++i) {
    if (!FindSegmentByNumber(pSegment->referred_to_segment_numbers_[i])) {
      return JBig2_Result::kFailure;
    }
  }

  FX_SAFE_UINT32 dwNumSyms = 0;
  for (int32_t i = 0; i < pSegment->referred_to_segment_count_; ++i) {
    CJBig2_Segment* pSeg =
        FindSegmentByNumber(pSegment->referred_to_segment_numbers_[i]);
    if (pSeg->flags_.s.type == 0) {
      dwNumSyms += pSeg->symbol_dict_->NumImages();
    }
  }
  pTRD->SBNUMSYMS = dwNumSyms.ValueOrDie();

  std::vector<UnownedPtr<CJBig2_Image>> SBSYMS(pTRD->SBNUMSYMS);
  if (!SBSYMS.empty()) {
    dwNumSyms = 0;
    for (int32_t i = 0; i < pSegment->referred_to_segment_count_; ++i) {
      CJBig2_Segment* pSeg =
          FindSegmentByNumber(pSegment->referred_to_segment_numbers_[i]);
      if (pSeg->flags_.s.type == 0) {
        const CJBig2_SymbolDict& dict = *pSeg->symbol_dict_;
        for (uint32_t j = 0; j < dict.NumImages(); ++j) {
          uint32_t dwIndex = (dwNumSyms + j).ValueOrDie();
          SBSYMS[dwIndex] = dict.GetImage(j);
        }
        dwNumSyms += dict.NumImages();
      }
    }
  }
  pTRD->SBSYMS = std::move(SBSYMS);

  if (pTRD->SBHUFF) {
    std::vector<JBig2HuffmanCode> SBSYMCODES =
        DecodeSymbolIDHuffmanTable(pTRD->SBNUMSYMS);
    if (SBSYMCODES.empty()) {
      return JBig2_Result::kFailure;
    }

    stream_->alignByte();
    pTRD->SBSYMCODES = std::move(SBSYMCODES);
  } else {
    dwTemp = 0;
    while ((uint32_t)(1 << dwTemp) < pTRD->SBNUMSYMS) {
      ++dwTemp;
    }
    pTRD->SBSYMCODELEN = (uint8_t)dwTemp;
  }

  if (pTRD->SBHUFF) {
    uint8_t cSBHUFFFS = wFlags & 0x0003;
    uint8_t cSBHUFFDS = (wFlags >> 2) & 0x0003;
    uint8_t cSBHUFFDT = (wFlags >> 4) & 0x0003;
    uint8_t cSBHUFFRDW = (wFlags >> 6) & 0x0003;
    uint8_t cSBHUFFRDH = (wFlags >> 8) & 0x0003;
    uint8_t cSBHUFFRDX = (wFlags >> 10) & 0x0003;
    uint8_t cSBHUFFRDY = (wFlags >> 12) & 0x0003;
    uint8_t cSBHUFFRSIZE = (wFlags >> 14) & 0x0001;
    if (cSBHUFFFS == 2 || cSBHUFFRDW == 2 || cSBHUFFRDH == 2 ||
        cSBHUFFRDX == 2 || cSBHUFFRDY == 2) {
      return JBig2_Result::kFailure;
    }
    int32_t nIndex = 0;
    if (cSBHUFFFS == 0) {
      pTRD->SBHUFFFS = GetHuffmanTable(6);
    } else if (cSBHUFFFS == 1) {
      pTRD->SBHUFFFS = GetHuffmanTable(7);
    } else {
      CJBig2_Segment* pSeg =
          FindReferredTableSegmentByIndex(pSegment, nIndex++);
      if (!pSeg) {
        return JBig2_Result::kFailure;
      }
      pTRD->SBHUFFFS = pSeg->huffman_table_.get();
    }
    if (cSBHUFFDS == 0) {
      pTRD->SBHUFFDS = GetHuffmanTable(8);
    } else if (cSBHUFFDS == 1) {
      pTRD->SBHUFFDS = GetHuffmanTable(9);
    } else if (cSBHUFFDS == 2) {
      pTRD->SBHUFFDS = GetHuffmanTable(10);
    } else {
      CJBig2_Segment* pSeg =
          FindReferredTableSegmentByIndex(pSegment, nIndex++);
      if (!pSeg) {
        return JBig2_Result::kFailure;
      }
      pTRD->SBHUFFDS = pSeg->huffman_table_.get();
    }
    if (cSBHUFFDT == 0) {
      pTRD->SBHUFFDT = GetHuffmanTable(11);
    } else if (cSBHUFFDT == 1) {
      pTRD->SBHUFFDT = GetHuffmanTable(12);
    } else if (cSBHUFFDT == 2) {
      pTRD->SBHUFFDT = GetHuffmanTable(13);
    } else {
      CJBig2_Segment* pSeg =
          FindReferredTableSegmentByIndex(pSegment, nIndex++);
      if (!pSeg) {
        return JBig2_Result::kFailure;
      }
      pTRD->SBHUFFDT = pSeg->huffman_table_.get();
    }
    if (cSBHUFFRDW == 0) {
      pTRD->SBHUFFRDW = GetHuffmanTable(14);
    } else if (cSBHUFFRDW == 1) {
      pTRD->SBHUFFRDW = GetHuffmanTable(15);
    } else {
      CJBig2_Segment* pSeg =
          FindReferredTableSegmentByIndex(pSegment, nIndex++);
      if (!pSeg) {
        return JBig2_Result::kFailure;
      }
      pTRD->SBHUFFRDW = pSeg->huffman_table_.get();
    }
    if (cSBHUFFRDH == 0) {
      pTRD->SBHUFFRDH = GetHuffmanTable(14);
    } else if (cSBHUFFRDH == 1) {
      pTRD->SBHUFFRDH = GetHuffmanTable(15);
    } else {
      CJBig2_Segment* pSeg =
          FindReferredTableSegmentByIndex(pSegment, nIndex++);
      if (!pSeg) {
        return JBig2_Result::kFailure;
      }
      pTRD->SBHUFFRDH = pSeg->huffman_table_.get();
    }
    if (cSBHUFFRDX == 0) {
      pTRD->SBHUFFRDX = GetHuffmanTable(14);
    } else if (cSBHUFFRDX == 1) {
      pTRD->SBHUFFRDX = GetHuffmanTable(15);
    } else {
      CJBig2_Segment* pSeg =
          FindReferredTableSegmentByIndex(pSegment, nIndex++);
      if (!pSeg) {
        return JBig2_Result::kFailure;
      }
      pTRD->SBHUFFRDX = pSeg->huffman_table_.get();
    }
    if (cSBHUFFRDY == 0) {
      pTRD->SBHUFFRDY = GetHuffmanTable(14);
    } else if (cSBHUFFRDY == 1) {
      pTRD->SBHUFFRDY = GetHuffmanTable(15);
    } else {
      CJBig2_Segment* pSeg =
          FindReferredTableSegmentByIndex(pSegment, nIndex++);
      if (!pSeg) {
        return JBig2_Result::kFailure;
      }
      pTRD->SBHUFFRDY = pSeg->huffman_table_.get();
    }
    if (cSBHUFFRSIZE == 0) {
      pTRD->SBHUFFRSIZE = GetHuffmanTable(1);
    } else {
      CJBig2_Segment* pSeg =
          FindReferredTableSegmentByIndex(pSegment, nIndex++);
      if (!pSeg) {
        return JBig2_Result::kFailure;
      }
      pTRD->SBHUFFRSIZE = pSeg->huffman_table_.get();
    }
  }
  FixedSizeDataVector<JBig2ArithCtx> grContexts;
  if (pTRD->SBREFINE) {
    const size_t size = GetRefAggContextSize(pTRD->SBRTEMPLATE);
    grContexts = FixedSizeDataVector<JBig2ArithCtx>::Zeroed(size);
  }
  pSegment->result_type_ = JBIG2_IMAGE_POINTER;
  if (pTRD->SBHUFF) {
    pSegment->image_ = pTRD->DecodeHuffman(stream_.get(), grContexts);
    if (!pSegment->image_) {
      return JBig2_Result::kFailure;
    }
    stream_->alignByte();
  } else {
    auto pArithDecoder = std::make_unique<CJBig2_ArithDecoder>(stream_.get());
    pSegment->image_ =
        pTRD->DecodeArith(pArithDecoder.get(), grContexts, nullptr);
    if (!pSegment->image_) {
      return JBig2_Result::kFailure;
    }
    stream_->alignByte();
    stream_->addOffset(2);
  }
  if (pSegment->flags_.s.type != 4) {
    if (!buf_specified_) {
      const auto& pPageInfo = page_info_list_.back();
      if (pPageInfo->is_striped_ && ri.y + ri.height > page_->height()) {
        page_->Expand(ri.y + ri.height, pPageInfo->default_pixel_value_);
      }
    }
    page_->ComposeFrom(ri.x, ri.y, pSegment->image_.get(),
                       (JBig2ComposeOp)(ri.flags & 0x03));
    pSegment->image_.reset();
  }
  return JBig2_Result::kSuccess;
}

JBig2_Result CJBig2_Context::ParsePatternDict(CJBig2_Segment* pSegment,
                                              PauseIndicatorIface* pPause) {
  uint8_t cFlags;
  auto pPDD = std::make_unique<CJBig2_PDDProc>();
  if (stream_->read1Byte(&cFlags) != 0 ||
      stream_->read1Byte(&pPDD->HDPW) != 0 ||
      stream_->read1Byte(&pPDD->HDPH) != 0 ||
      stream_->readInteger(&pPDD->GRAYMAX) != 0) {
    return JBig2_Result::kFailure;
  }
  if (pPDD->GRAYMAX > kJBig2MaxPatternIndex) {
    return JBig2_Result::kFailure;
  }

  pPDD->HDMMR = cFlags & 0x01;
  pPDD->HDTEMPLATE = (cFlags >> 1) & 0x03;
  pSegment->result_type_ = JBIG2_PATTERN_DICT_POINTER;
  if (pPDD->HDMMR) {
    pSegment->pattern_dict_ = pPDD->DecodeMMR(stream_.get());
    if (!pSegment->pattern_dict_) {
      return JBig2_Result::kFailure;
    }
    stream_->alignByte();
  } else {
    const size_t size = GetHuffContextSize(pPDD->HDTEMPLATE);
    auto gbContexts = FixedSizeDataVector<JBig2ArithCtx>::Zeroed(size);
    auto pArithDecoder = std::make_unique<CJBig2_ArithDecoder>(stream_.get());
    pSegment->pattern_dict_ =
        pPDD->DecodeArith(pArithDecoder.get(), gbContexts, pPause);
    if (!pSegment->pattern_dict_) {
      return JBig2_Result::kFailure;
    }

    stream_->alignByte();
    stream_->addOffset(2);
  }
  return JBig2_Result::kSuccess;
}

JBig2_Result CJBig2_Context::ParseHalftoneRegion(CJBig2_Segment* pSegment,
                                                 PauseIndicatorIface* pPause) {
  uint8_t cFlags;
  JBig2RegionInfo ri;
  auto pHRD = std::make_unique<CJBig2_HTRDProc>();
  if (ParseRegionInfo(&ri) != JBig2_Result::kSuccess ||
      stream_->read1Byte(&cFlags) != 0 ||
      stream_->readInteger(&pHRD->HGW) != 0 ||
      stream_->readInteger(&pHRD->HGH) != 0 ||
      stream_->readInteger((uint32_t*)&pHRD->HGX) != 0 ||
      stream_->readInteger((uint32_t*)&pHRD->HGY) != 0 ||
      stream_->readShortInteger(&pHRD->HRX) != 0 ||
      stream_->readShortInteger(&pHRD->HRY) != 0) {
    return JBig2_Result::kFailure;
  }

  if (!CJBig2_Image::IsValidImageSize(pHRD->HGW, pHRD->HGH)) {
    return JBig2_Result::kFailure;
  }

  if (!CJBig2_Image::IsValidImageSize(ri.width, ri.height)) {
    return JBig2_Result::kFailure;
  }

  pHRD->HBW = ri.width;
  pHRD->HBH = ri.height;
  pHRD->HMMR = cFlags & 0x01;
  pHRD->HTEMPLATE = (cFlags >> 1) & 0x03;
  pHRD->HENABLESKIP = (cFlags >> 3) & 0x01;
  pHRD->HCOMBOP = (JBig2ComposeOp)((cFlags >> 4) & 0x07);
  pHRD->HDEFPIXEL = (cFlags >> 7) & 0x01;
  if (pSegment->referred_to_segment_count_ != 1) {
    return JBig2_Result::kFailure;
  }

  CJBig2_Segment* pSeg =
      FindSegmentByNumber(pSegment->referred_to_segment_numbers_[0]);
  if (!pSeg || (pSeg->flags_.s.type != 16)) {
    return JBig2_Result::kFailure;
  }

  const CJBig2_PatternDict* pPatternDict = pSeg->pattern_dict_.get();
  if (!pPatternDict || (pPatternDict->NUMPATS == 0)) {
    return JBig2_Result::kFailure;
  }

  pHRD->HNUMPATS = pPatternDict->NUMPATS;
  pHRD->HPATS = &pPatternDict->HDPATS;
  pHRD->HPW = pPatternDict->HDPATS[0]->width();
  pHRD->HPH = pPatternDict->HDPATS[0]->height();
  pSegment->result_type_ = JBIG2_IMAGE_POINTER;
  if (pHRD->HMMR) {
    pSegment->image_ = pHRD->DecodeMMR(stream_.get());
    if (!pSegment->image_) {
      return JBig2_Result::kFailure;
    }
    stream_->alignByte();
  } else {
    const size_t size = GetHuffContextSize(pHRD->HTEMPLATE);
    auto gbContexts = FixedSizeDataVector<JBig2ArithCtx>::Zeroed(size);
    auto pArithDecoder = std::make_unique<CJBig2_ArithDecoder>(stream_.get());
    pSegment->image_ =
        pHRD->DecodeArith(pArithDecoder.get(), gbContexts, pPause);
    if (!pSegment->image_) {
      return JBig2_Result::kFailure;
    }

    stream_->alignByte();
    stream_->addOffset(2);
  }
  if (pSegment->flags_.s.type != 20) {
    if (!buf_specified_) {
      const auto& pPageInfo = page_info_list_.back();
      if (pPageInfo->is_striped_ && ri.y + ri.height > page_->height()) {
        page_->Expand(ri.y + ri.height, pPageInfo->default_pixel_value_);
      }
    }
    page_->ComposeFrom(ri.x, ri.y, pSegment->image_.get(),
                       (JBig2ComposeOp)(ri.flags & 0x03));
    pSegment->image_.reset();
  }
  return JBig2_Result::kSuccess;
}

JBig2_Result CJBig2_Context::ParseGenericRegion(CJBig2_Segment* pSegment,
                                                PauseIndicatorIface* pPause) {
  if (!grd_) {
    auto pGRD = std::make_unique<CJBig2_GRDProc>();
    uint8_t cFlags;
    if (ParseRegionInfo(&ri_) != JBig2_Result::kSuccess ||
        stream_->read1Byte(&cFlags) != 0) {
      return JBig2_Result::kFailure;
    }
    if (ri_.height < 0 || ri_.width < 0) {
      return JBig2_Result::kFailure;
    }
    pGRD->GBW = ri_.width;
    pGRD->GBH = ri_.height;
    pGRD->MMR = cFlags & 0x01;
    pGRD->GBTEMPLATE = (cFlags >> 1) & 0x03;
    pGRD->TPGDON = (cFlags >> 3) & 0x01;
    if (!pGRD->MMR) {
      if (pGRD->GBTEMPLATE == 0) {
        for (int32_t i = 0; i < 8; ++i) {
          if (stream_->read1Byte((uint8_t*)&pGRD->GBAT[i]) != 0) {
            return JBig2_Result::kFailure;
          }
        }
      } else {
        for (int32_t i = 0; i < 2; ++i) {
          if (stream_->read1Byte((uint8_t*)&pGRD->GBAT[i]) != 0) {
            return JBig2_Result::kFailure;
          }
        }
      }
    }
    pGRD->USESKIP = false;
    grd_ = std::move(pGRD);
  }
  pSegment->result_type_ = JBIG2_IMAGE_POINTER;
  if (grd_->MMR) {
    grd_->StartDecodeMMR(&pSegment->image_, stream_.get());
    if (!pSegment->image_) {
      grd_.reset();
      return JBig2_Result::kFailure;
    }
    stream_->alignByte();
  } else {
    if (gb_contexts_.empty()) {
      gb_contexts_.resize(GetHuffContextSize(grd_->GBTEMPLATE));
    }

    bool bStart = !arith_decoder_;
    if (bStart) {
      arith_decoder_ = std::make_unique<CJBig2_ArithDecoder>(stream_.get());
    }
    {
      // |state.gbContexts| can't exist when gb_contexts_.clear() called below.
      CJBig2_GRDProc::ProgressiveArithDecodeState state;
      state.pImage = &pSegment->image_;
      state.pArithDecoder = arith_decoder_.get();
      state.gbContexts = gb_contexts_;
      state.pPause = pPause;
      processing_status_ = bStart ? grd_->StartDecodeArith(&state)
                                  : grd_->ContinueDecode(&state);
      if (processing_status_ == FXCODEC_STATUS::kDecodeToBeContinued) {
        if (pSegment->flags_.s.type != 36) {
          if (!buf_specified_) {
            const auto& pPageInfo = page_info_list_.back();
            if (pPageInfo->is_striped_ &&
                ri_.y + ri_.height > page_->height()) {
              page_->Expand(ri_.y + ri_.height,
                            pPageInfo->default_pixel_value_);
            }
          }
          const FX_RECT& rect = grd_->GetReplaceRect();
          page_->ComposeFromWithRect(ri_.x + rect.left, ri_.y + rect.top,
                                     pSegment->image_.get(), rect,
                                     (JBig2ComposeOp)(ri_.flags & 0x03));
        }
        return JBig2_Result::kSuccess;
      }
    }
    arith_decoder_.reset();
    gb_contexts_.clear();
    if (!pSegment->image_) {
      processing_status_ = FXCODEC_STATUS::kError;
      grd_.reset();
      return JBig2_Result::kFailure;
    }
    stream_->alignByte();
    stream_->addOffset(2);
  }
  if (pSegment->flags_.s.type != 36) {
    if (!buf_specified_) {
      JBig2PageInfo* pPageInfo = page_info_list_.back().get();
      if (pPageInfo->is_striped_ && ri_.y + ri_.height > page_->height()) {
        page_->Expand(ri_.y + ri_.height, pPageInfo->default_pixel_value_);
      }
    }
    const FX_RECT& rect = grd_->GetReplaceRect();
    page_->ComposeFromWithRect(ri_.x + rect.left, ri_.y + rect.top,
                               pSegment->image_.get(), rect,
                               (JBig2ComposeOp)(ri_.flags & 0x03));
    pSegment->image_.reset();
  }
  grd_.reset();
  return JBig2_Result::kSuccess;
}

JBig2_Result CJBig2_Context::ParseGenericRefinementRegion(
    CJBig2_Segment* pSegment) {
  JBig2RegionInfo ri;
  uint8_t cFlags;
  if (ParseRegionInfo(&ri) != JBig2_Result::kSuccess ||
      stream_->read1Byte(&cFlags) != 0) {
    return JBig2_Result::kFailure;
  }
  if (!CJBig2_Image::IsValidImageSize(ri.width, ri.height)) {
    return JBig2_Result::kFailure;
  }

  auto pGRRD = std::make_unique<CJBig2_GRRDProc>();
  pGRRD->GRW = ri.width;
  pGRRD->GRH = ri.height;
  pGRRD->GRTEMPLATE = !!(cFlags & 0x01);
  pGRRD->TPGRON = (cFlags >> 1) & 0x01;
  if (!pGRRD->GRTEMPLATE) {
    for (int32_t i = 0; i < 4; ++i) {
      if (stream_->read1Byte((uint8_t*)&pGRRD->GRAT[i]) != 0) {
        return JBig2_Result::kFailure;
      }
    }
  }
  CJBig2_Segment* pSeg = nullptr;
  if (pSegment->referred_to_segment_count_ > 0) {
    int32_t i;
    for (i = 0; i < pSegment->referred_to_segment_count_; ++i) {
      pSeg = FindSegmentByNumber(pSegment->referred_to_segment_numbers_[0]);
      if (!pSeg) {
        return JBig2_Result::kFailure;
      }

      if (pSeg->flags_.s.type == 4 || pSeg->flags_.s.type == 20 ||
          pSeg->flags_.s.type == 36 || pSeg->flags_.s.type == 40) {
        break;
      }
    }
    if (i >= pSegment->referred_to_segment_count_) {
      return JBig2_Result::kFailure;
    }

    pGRRD->GRREFERENCE = pSeg->image_.get();
  } else {
    pGRRD->GRREFERENCE = page_.get();
  }
  pGRRD->GRREFERENCEDX = 0;
  pGRRD->GRREFERENCEDY = 0;
  const size_t size = GetRefAggContextSize(pGRRD->GRTEMPLATE);
  auto grContexts = FixedSizeDataVector<JBig2ArithCtx>::Zeroed(size);
  auto pArithDecoder = std::make_unique<CJBig2_ArithDecoder>(stream_.get());
  pSegment->result_type_ = JBIG2_IMAGE_POINTER;
  pSegment->image_ = pGRRD->Decode(pArithDecoder.get(), grContexts);
  if (!pSegment->image_) {
    return JBig2_Result::kFailure;
  }

  stream_->alignByte();
  stream_->addOffset(2);
  if (pSegment->flags_.s.type != 40) {
    if (!buf_specified_) {
      JBig2PageInfo* pPageInfo = page_info_list_.back().get();
      if (pPageInfo->is_striped_ && ri.y + ri.height > page_->height()) {
        page_->Expand(ri.y + ri.height, pPageInfo->default_pixel_value_);
      }
    }
    page_->ComposeFrom(ri.x, ri.y, pSegment->image_.get(),
                       (JBig2ComposeOp)(ri.flags & 0x03));
    pSegment->image_.reset();
  }
  return JBig2_Result::kSuccess;
}

JBig2_Result CJBig2_Context::ParseTable(CJBig2_Segment* pSegment) {
  pSegment->result_type_ = JBIG2_HUFFMAN_TABLE_POINTER;
  pSegment->huffman_table_.reset();
  auto pHuff = std::make_unique<CJBig2_HuffmanTable>(stream_.get());
  if (!pHuff->IsOK()) {
    return JBig2_Result::kFailure;
  }

  pSegment->huffman_table_ = std::move(pHuff);
  stream_->alignByte();
  return JBig2_Result::kSuccess;
}

JBig2_Result CJBig2_Context::ParseRegionInfo(JBig2RegionInfo* pRI) {
  if (stream_->readInteger((uint32_t*)&pRI->width) != 0 ||
      stream_->readInteger((uint32_t*)&pRI->height) != 0 ||
      stream_->readInteger((uint32_t*)&pRI->x) != 0 ||
      stream_->readInteger((uint32_t*)&pRI->y) != 0 ||
      stream_->read1Byte(&pRI->flags) != 0) {
    return JBig2_Result::kFailure;
  }
  return JBig2_Result::kSuccess;
}

std::vector<JBig2HuffmanCode> CJBig2_Context::DecodeSymbolIDHuffmanTable(
    uint32_t SBNUMSYMS) {
  const size_t kRunCodesSize = 35;
  std::array<JBig2HuffmanCode, kRunCodesSize> huffman_codes;
  for (size_t i = 0; i < kRunCodesSize; ++i) {
    if (stream_->readNBits(4, &huffman_codes[i].codelen) != 0) {
      return std::vector<JBig2HuffmanCode>();
    }
  }
  if (!HuffmanAssignCode(huffman_codes)) {
    return std::vector<JBig2HuffmanCode>();
  }

  std::vector<JBig2HuffmanCode> SBSYMCODES(SBNUMSYMS);
  int32_t run = 0;
  int32_t i = 0;
  while (i < static_cast<int>(SBNUMSYMS)) {
    size_t j;
    FX_SAFE_INT32 nSafeVal = 0;
    int32_t nBits = 0;
    uint32_t nTemp;
    while (true) {
      if (stream_->read1Bit(&nTemp) != 0) {
        return std::vector<JBig2HuffmanCode>();
      }

      nSafeVal <<= 1;
      if (!nSafeVal.IsValid()) {
        return std::vector<JBig2HuffmanCode>();
      }

      nSafeVal |= nTemp;
      ++nBits;
      const int32_t nVal = nSafeVal.ValueOrDie();
      for (j = 0; j < kRunCodesSize; ++j) {
        if (nBits == huffman_codes[j].codelen &&
            nVal == huffman_codes[j].code) {
          break;
        }
      }
      if (j < kRunCodesSize) {
        break;
      }
    }
    int32_t runcode = static_cast<int32_t>(j);
    if (runcode < 32) {
      SBSYMCODES[i].codelen = runcode;
      run = 0;
    } else if (runcode == 32) {
      if (stream_->readNBits(2, &nTemp) != 0) {
        return std::vector<JBig2HuffmanCode>();
      }
      run = nTemp + 3;
    } else if (runcode == 33) {
      if (stream_->readNBits(3, &nTemp) != 0) {
        return std::vector<JBig2HuffmanCode>();
      }
      run = nTemp + 3;
    } else if (runcode == 34) {
      if (stream_->readNBits(7, &nTemp) != 0) {
        return std::vector<JBig2HuffmanCode>();
      }
      run = nTemp + 11;
    }
    if (run > 0) {
      if (i + run > (int)SBNUMSYMS) {
        return std::vector<JBig2HuffmanCode>();
      }
      for (int32_t k = 0; k < run; ++k) {
        if (runcode == 32 && i > 0) {
          SBSYMCODES[i + k].codelen = SBSYMCODES[i - 1].codelen;
        } else {
          SBSYMCODES[i + k].codelen = 0;
        }
      }
      i += run;
    } else {
      ++i;
    }
  }
  if (!HuffmanAssignCode(SBSYMCODES)) {
    return std::vector<JBig2HuffmanCode>();
  }
  return SBSYMCODES;
}

const CJBig2_HuffmanTable* CJBig2_Context::GetHuffmanTable(size_t idx) {
  DCHECK(idx > 0);
  DCHECK(idx < CJBig2_HuffmanTable::kNumHuffmanTables);
  if (!huffman_tables_[idx].get()) {
    huffman_tables_[idx] = std::make_unique<CJBig2_HuffmanTable>(idx);
  }
  return huffman_tables_[idx].get();
}

// static
bool CJBig2_Context::HuffmanAssignCode(
    pdfium::span<JBig2HuffmanCode> symcodes) {
  int lenmax = 0;
  for (const auto& symcode : symcodes) {
    lenmax = std::max(symcode.codelen, lenmax);
  }
  std::vector<int> lencounts(lenmax + 1);
  std::vector<int> firstcodes(lenmax + 1);
  for (const auto& symcode : symcodes) {
    ++lencounts[symcode.codelen];
  }
  lencounts[0] = 0;
  for (int i = 1; i <= lenmax; ++i) {
    FX_SAFE_INT32 shifted = firstcodes[i - 1];
    shifted += lencounts[i - 1];
    shifted <<= 1;
    if (!shifted.IsValid()) {
      return false;
    }
    firstcodes[i] = shifted.ValueOrDie();
    int curcode = firstcodes[i];
    for (auto& symcode : symcodes) {
      if (symcode.codelen == i) {
        symcode.code = curcode++;
      }
    }
  }
  return true;
}
