// 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/ccodec_jbig2module.h"

#include <list>
#include <memory>

#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fxcodec/JBig2_DocumentContext.h"
#include "core/fxcodec/jbig2/JBig2_Context.h"
#include "core/fxcodec/jbig2/JBig2_Image.h"
#include "third_party/base/ptr_util.h"

JBig2_DocumentContext::JBig2_DocumentContext() {}

JBig2_DocumentContext::~JBig2_DocumentContext() {}

JBig2_DocumentContext* GetJBig2DocumentContext(
    std::unique_ptr<JBig2_DocumentContext>* pContextHolder) {
  if (!pContextHolder->get())
    *pContextHolder = pdfium::MakeUnique<JBig2_DocumentContext>();
  return pContextHolder->get();
}

CCodec_Jbig2Context::CCodec_Jbig2Context()
    : m_width(0),
      m_height(0),
      m_pGlobalStream(nullptr),
      m_pSrcStream(nullptr),
      m_dest_buf(0),
      m_dest_pitch(0) {}

CCodec_Jbig2Context::~CCodec_Jbig2Context() {}

CCodec_Jbig2Module::~CCodec_Jbig2Module() {}

FXCODEC_STATUS CCodec_Jbig2Module::StartDecode(
    CCodec_Jbig2Context* pJbig2Context,
    std::unique_ptr<JBig2_DocumentContext>* pContextHolder,
    uint32_t width,
    uint32_t height,
    const RetainPtr<CPDF_StreamAcc>& src_stream,
    const RetainPtr<CPDF_StreamAcc>& global_stream,
    uint8_t* dest_buf,
    uint32_t dest_pitch,
    PauseIndicatorIface* pPause) {
  if (!pJbig2Context)
    return FXCODEC_STATUS_ERR_PARAMS;

  JBig2_DocumentContext* pJBig2DocumentContext =
      GetJBig2DocumentContext(pContextHolder);
  pJbig2Context->m_width = width;
  pJbig2Context->m_height = height;
  pJbig2Context->m_pSrcStream = src_stream;
  pJbig2Context->m_pGlobalStream = global_stream;
  pJbig2Context->m_dest_buf = dest_buf;
  pJbig2Context->m_dest_pitch = dest_pitch;
  memset(dest_buf, 0, height * dest_pitch);
  pJbig2Context->m_pContext = CJBig2_Context::Create(
      global_stream, src_stream, pJBig2DocumentContext->GetSymbolDictCache());
  bool succeeded = pJbig2Context->m_pContext->GetFirstPage(
      dest_buf, width, height, dest_pitch, pPause);
  return Decode(pJbig2Context, succeeded);
}

FXCODEC_STATUS CCodec_Jbig2Module::ContinueDecode(
    CCodec_Jbig2Context* pJbig2Context,
    PauseIndicatorIface* pPause) {
  bool succeeded = pJbig2Context->m_pContext->Continue(pPause);
  return Decode(pJbig2Context, succeeded);
}

FXCODEC_STATUS CCodec_Jbig2Module::Decode(CCodec_Jbig2Context* pJbig2Context,
                                          bool decode_success) {
  FXCODEC_STATUS status = pJbig2Context->m_pContext->GetProcessingStatus();
  if (status != FXCODEC_STATUS_DECODE_FINISH)
    return status;

  pJbig2Context->m_pContext.reset();
  if (!decode_success)
    return FXCODEC_STATUS_ERROR;

  int dword_size = pJbig2Context->m_height * pJbig2Context->m_dest_pitch / 4;
  uint32_t* dword_buf = reinterpret_cast<uint32_t*>(pJbig2Context->m_dest_buf);
  for (int i = 0; i < dword_size; i++)
    dword_buf[i] = ~dword_buf[i];
  return FXCODEC_STATUS_DECODE_FINISH;
}
