// Copyright 2015 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_HtrdProc.h"

#include <algorithm>
#include <utility>

#include "core/fxcodec/jbig2/JBig2_BitStream.h"
#include "core/fxcodec/jbig2/JBig2_GrdProc.h"
#include "core/fxcodec/jbig2/JBig2_Image.h"
#include "core/fxcrt/zip.h"

CJBig2_HTRDProc::CJBig2_HTRDProc() = default;

CJBig2_HTRDProc::~CJBig2_HTRDProc() = default;

std::unique_ptr<CJBig2_Image> CJBig2_HTRDProc::DecodeArith(
    CJBig2_ArithDecoder* pArithDecoder,
    pdfium::span<JBig2ArithCtx> gbContexts,
    PauseIndicatorIface* pPause) {
  std::unique_ptr<CJBig2_Image> HSKIP;
  if (HENABLESKIP == 1) {
    HSKIP = std::make_unique<CJBig2_Image>(HGW, HGH);
    for (uint32_t mg = 0; mg < HGH; ++mg) {
      pdfium::span<uint8_t> row_write = HSKIP->GetLine(mg);
      // See comment in the inner-loop below re: casting.
      const int64_t row_x = HGX + static_cast<int64_t>(mg) * HRY;
      const int64_t row_y = HGY + static_cast<int64_t>(mg) * HRX;
      for (uint32_t ng = 0; ng < HGW; ++ng) {
        // The `>> 8` is an arithmetic shift per spec.  Cast mg, ng to int,
        // else implicit conversions would evaluate it as unsigned shift.
        // HGX / HGY are 32 bit, HRX / HRY 16, mg / ng 32.
        // The result after >> 8 fits in about 42 bit; int64_t suffices.
        int64_t x = (row_x + static_cast<int64_t>(ng) * HRX) >> 8;
        int64_t y = (row_y - static_cast<int64_t>(ng) * HRY) >> 8;

        bool out_of_bounds = (x + HPW <= 0) | (x >= static_cast<int32_t>(HBW)) |
                             (y + HPH <= 0) | (y >= static_cast<int32_t>(HBH));
        HSKIP->SetPixel(ng, row_write, out_of_bounds ? 1 : 0);
      }
    }
  }
  uint32_t HBPP = 1;
  while (static_cast<uint32_t>(1 << HBPP) < HNUMPATS) {
    ++HBPP;
  }

  CJBig2_GRDProc GRD;
  GRD.MMR = HMMR;
  GRD.GBW = HGW;
  GRD.GBH = HGH;
  GRD.GBTEMPLATE = HTEMPLATE;
  GRD.TPGDON = false;
  GRD.USESKIP = HENABLESKIP;
  GRD.SKIP = HSKIP.get();
  if (HTEMPLATE <= 1) {
    GRD.GBAT[0] = 3;
  } else {
    GRD.GBAT[0] = 2;
  }
  GRD.GBAT[1] = -1;
  if (GRD.GBTEMPLATE == 0) {
    GRD.GBAT[2] = -3;
    GRD.GBAT[3] = -1;
    GRD.GBAT[4] = 2;
    GRD.GBAT[5] = -2;
    GRD.GBAT[6] = -2;
    GRD.GBAT[7] = -2;
  }

  uint8_t GSBPP = static_cast<uint8_t>(HBPP);
  std::vector<std::unique_ptr<CJBig2_Image>> GSPLANES(GSBPP);
  for (int32_t i = GSBPP - 1; i >= 0; --i) {
    std::unique_ptr<CJBig2_Image> pImage;
    CJBig2_GRDProc::ProgressiveArithDecodeState state;
    state.pImage = &pImage;
    state.pArithDecoder = pArithDecoder;
    state.gbContexts = gbContexts;
    state.pPause = nullptr;
    FXCODEC_STATUS status = GRD.StartDecodeArith(&state);
    state.pPause = pPause;
    while (status == FXCODEC_STATUS::kDecodeToBeContinued) {
      status = GRD.ContinueDecode(&state);
    }
    GRD.FinishDecode();
    if (!pImage) {
      return nullptr;
    }

    GSPLANES[i] = std::move(pImage);
    if (i < GSBPP - 1) {
      GSPLANES[i]->ComposeFrom(0, 0, GSPLANES[i + 1].get(), JBIG2_COMPOSE_XOR);
    }
  }
  return DecodeImage(GSPLANES);
}

std::unique_ptr<CJBig2_Image> CJBig2_HTRDProc::DecodeMMR(
    CJBig2_BitStream* pStream) {
  uint32_t HBPP = 1;
  while (static_cast<uint32_t>(1 << HBPP) < HNUMPATS) {
    ++HBPP;
  }

  CJBig2_GRDProc GRD;
  GRD.MMR = HMMR;
  GRD.GBW = HGW;
  GRD.GBH = HGH;

  uint8_t GSBPP = static_cast<uint8_t>(HBPP);
  std::vector<std::unique_ptr<CJBig2_Image>> GSPLANES(GSBPP);
  GRD.StartDecodeMMR(&GSPLANES[GSBPP - 1], pStream);
  if (!GSPLANES[GSBPP - 1]) {
    return nullptr;
  }

  pStream->alignByte();
  pStream->addOffset(3);
  for (int32_t J = GSBPP - 2; J >= 0; --J) {
    GRD.StartDecodeMMR(&GSPLANES[J], pStream);
    if (!GSPLANES[J]) {
      return nullptr;
    }

    pStream->alignByte();
    pStream->addOffset(3);
    GSPLANES[J]->ComposeFrom(0, 0, GSPLANES[J + 1].get(), JBIG2_COMPOSE_XOR);
  }
  return DecodeImage(GSPLANES);
}

std::unique_ptr<CJBig2_Image> CJBig2_HTRDProc::DecodeImage(
    const std::vector<std::unique_ptr<CJBig2_Image>>& GSPLANES) {
  auto HTREG = std::make_unique<CJBig2_Image>(HBW, HBH);
  if (!HTREG->has_data()) {
    return nullptr;
  }

  HTREG->Fill(HDEFPIXEL);
  for (uint32_t mg = 0; mg < HGH; ++mg) {
    std::vector<pdfium::span<uint8_t>> rows(GSPLANES.size());
    for (auto [plane, row] : fxcrt::Zip(GSPLANES, rows)) {
      row = plane->GetLine(mg);
    }

    // See comment in the inner-loop below re: casting.
    const int64_t row_x = HGX + static_cast<int64_t>(mg) * HRY;
    const int64_t row_y = HGY + static_cast<int64_t>(mg) * HRX;
    for (uint32_t ng = 0; ng < HGW; ++ng) {
      uint32_t gsval = 0;
      for (uint8_t i = 0; i < GSPLANES.size(); ++i) {
        gsval |= GSPLANES[i]->GetPixel(ng, rows[i]) << i;
      }
      uint32_t pat_index = std::min(gsval, HNUMPATS - 1);
      // The `>> 8` is an arithmetic shift per spec.  Cast mg, ng to int,
      // else implicit conversions would evaluate it as unsigned shift.
      // HGX / HGY are 32 bit, HRX / HRY 16, mg / ng 32.
      // The result after >> 8 fits in about 42 bit; int64_t suffices.
      int64_t x = (row_x + static_cast<int64_t>(ng) * HRX) >> 8;
      int64_t y = (row_y - static_cast<int64_t>(ng) * HRY) >> 8;
      (*HPATS)[pat_index]->ComposeTo(HTREG.get(), x, y, HCOMBOP);
    }
  }
  return HTREG;
}
