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

#include <memory>
#include <utility>

#include "core/fxcodec/cfx_codec_memory.h"
#include "core/fxcodec/fx_codec.h"
#include "core/fxcodec/fx_codec_def.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_memcpy_wrappers.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/fx_stream.h"
#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/notreached.h"
#include "core/fxcrt/numerics/safe_conversions.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/span.h"
#include "core/fxcrt/span_util.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "core/fxge/dib/fx_dib.h"

extern "C" {
#if defined(USE_SYSTEM_LIBTIFF)
#include <tiffio.h>
#else
#include "third_party/libtiff/tiffio.h"
#endif
}  // extern C

namespace {

// For use with std::unique_ptr<TIFF>.
struct TiffDeleter {
  inline void operator()(TIFF* context) { TIFFClose(context); }
};

// For use with std::unique_ptr<TIFFOpenOptions>.
struct TIFFOpenOptionsDeleter {
  inline void operator()(TIFFOpenOptions* options) {
    TIFFOpenOptionsFree(options);
  }
};

}  // namespace

class CTiffContext final : public ProgressiveDecoderIface::Context {
 public:
  CTiffContext() = default;
  ~CTiffContext() override = default;

  bool InitDecoder(const RetainPtr<IFX_SeekableReadStream>& file_ptr);
  bool LoadFrameInfo(int32_t frame,
                     int32_t* width,
                     int32_t* height,
                     int32_t* comps,
                     int32_t* bpc,
                     CFX_DIBAttribute* pAttribute);
  bool Decode(RetainPtr<CFX_DIBitmap> bitmap);

  RetainPtr<IFX_SeekableReadStream> io_in() const { return io_in_; }
  uint32_t offset() const { return offset_; }
  void set_offset(uint32_t offset) { offset_ = offset; }

 private:
  RetainPtr<IFX_SeekableReadStream> io_in_;
  uint32_t offset_ = 0;
  std::unique_ptr<TIFF, TiffDeleter> tif_ctx_;
};

void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz) {
  return FXMEM_DefaultCalloc(nmemb, siz);
}

void* _TIFFmalloc(tmsize_t size) {
  return FXMEM_DefaultAlloc(size);
}

void _TIFFfree(void* ptr) {
  if (ptr) {
    FXMEM_DefaultFree(ptr);
  }
}

void* _TIFFrealloc(void* ptr, tmsize_t size) {
  return FXMEM_DefaultRealloc(ptr, size);
}

void _TIFFmemset(void* ptr, int val, tmsize_t size) {
  UNSAFE_TODO(FXSYS_memset(ptr, val, static_cast<size_t>(size)));
}

void _TIFFmemcpy(void* des, const void* src, tmsize_t size) {
  UNSAFE_TODO(FXSYS_memcpy(des, src, static_cast<size_t>(size)));
}

int _TIFFmemcmp(const void* ptr1, const void* ptr2, tmsize_t size) {
  return UNSAFE_TODO(memcmp(ptr1, ptr2, static_cast<size_t>(size)));
}

namespace {

tsize_t tiff_read(thandle_t context, tdata_t buf, tsize_t length) {
  CTiffContext* pTiffContext = reinterpret_cast<CTiffContext*>(context);
  FX_SAFE_UINT32 increment = pTiffContext->offset();
  increment += length;
  if (!increment.IsValid()) {
    return 0;
  }

  FX_FILESIZE offset = pTiffContext->offset();
  // SAFETY: required from caller.
  if (!pTiffContext->io_in()->ReadBlockAtOffset(
          UNSAFE_BUFFERS(pdfium::span(static_cast<uint8_t*>(buf),
                                      static_cast<size_t>(length))),
          offset)) {
    return 0;
  }
  pTiffContext->set_offset(increment.ValueOrDie());
  if (offset + length > pTiffContext->io_in()->GetSize()) {
    return pdfium::checked_cast<tsize_t>(pTiffContext->io_in()->GetSize() -
                                         offset);
  }
  return length;
}

tsize_t tiff_write(thandle_t context, tdata_t buf, tsize_t length) {
  NOTREACHED();
}

toff_t tiff_seek(thandle_t context, toff_t offset, int whence) {
  CTiffContext* pTiffContext = reinterpret_cast<CTiffContext*>(context);
  FX_SAFE_FILESIZE safe_offset = offset;
  if (!safe_offset.IsValid()) {
    return static_cast<toff_t>(-1);
  }
  FX_FILESIZE file_offset = safe_offset.ValueOrDie();

  switch (whence) {
    case 0: {
      if (file_offset > pTiffContext->io_in()->GetSize()) {
        return static_cast<toff_t>(-1);
      }
      pTiffContext->set_offset(pdfium::checked_cast<uint32_t>(file_offset));
      return pTiffContext->offset();
    }
    case 1: {
      FX_SAFE_UINT32 new_increment = pTiffContext->offset();
      new_increment += file_offset;
      if (!new_increment.IsValid()) {
        return static_cast<toff_t>(-1);
      }
      pTiffContext->set_offset(new_increment.ValueOrDie());
      return pTiffContext->offset();
    }
    case 2: {
      if (pTiffContext->io_in()->GetSize() < file_offset) {
        return static_cast<toff_t>(-1);
      }
      pTiffContext->set_offset(pdfium::checked_cast<uint32_t>(
          pTiffContext->io_in()->GetSize() - file_offset));
      return pTiffContext->offset();
    }
    default:
      return static_cast<toff_t>(-1);
  }
}

int tiff_close(thandle_t context) {
  return 0;
}

toff_t tiff_get_size(thandle_t context) {
  CTiffContext* pTiffContext = reinterpret_cast<CTiffContext*>(context);
  return static_cast<toff_t>(pTiffContext->io_in()->GetSize());
}

int tiff_map(thandle_t context, tdata_t*, toff_t*) {
  return 0;
}

void tiff_unmap(thandle_t context, tdata_t, toff_t) {}

}  // namespace

bool CTiffContext::InitDecoder(
    const RetainPtr<IFX_SeekableReadStream>& file_ptr) {
  // Limit set to make fuzzers happy. If this causes problems in the real world,
  // then adjust as needed.
  static constexpr tmsize_t kMaxTiffAllocBytes = 1536 * 1024 * 1024;  // 1.5 GB
  std::unique_ptr<TIFFOpenOptions, TIFFOpenOptionsDeleter> options(
      TIFFOpenOptionsAlloc());
  CHECK(options);
  TIFFOpenOptionsSetMaxCumulatedMemAlloc(options.get(), kMaxTiffAllocBytes);

  io_in_ = file_ptr;
  tif_ctx_.reset(TIFFClientOpenExt(
      /*name=*/"Tiff Image", /*mode=*/"r", /*clientdata=*/this, tiff_read,
      tiff_write, tiff_seek, tiff_close, tiff_get_size, tiff_map, tiff_unmap,
      options.get()));
  return !!tif_ctx_;
}

bool CTiffContext::LoadFrameInfo(int32_t frame,
                                 int32_t* width,
                                 int32_t* height,
                                 int32_t* comps,
                                 int32_t* bpc,
                                 CFX_DIBAttribute* pAttribute) {
  if (!TIFFSetDirectory(tif_ctx_.get(), (uint16_t)frame)) {
    return false;
  }

  uint32_t tif_width = 0;
  uint32_t tif_height = 0;
  uint16_t tif_comps = 0;
  uint16_t tif_bpc = 0;
  uint32_t tif_rps = 0;
  TIFFGetField(tif_ctx_.get(), TIFFTAG_IMAGEWIDTH, &tif_width);
  TIFFGetField(tif_ctx_.get(), TIFFTAG_IMAGELENGTH, &tif_height);
  TIFFGetField(tif_ctx_.get(), TIFFTAG_SAMPLESPERPIXEL, &tif_comps);
  TIFFGetField(tif_ctx_.get(), TIFFTAG_BITSPERSAMPLE, &tif_bpc);
  TIFFGetField(tif_ctx_.get(), TIFFTAG_ROWSPERSTRIP, &tif_rps);

  uint16_t tif_resunit = 0;
  if (TIFFGetField(tif_ctx_.get(), TIFFTAG_RESOLUTIONUNIT, &tif_resunit)) {
    pAttribute->dpi_unit_ =
        static_cast<CFX_DIBAttribute::ResUnit>(tif_resunit - 1);
  } else {
    pAttribute->dpi_unit_ = CFX_DIBAttribute::kResUnitInch;
  }

  float tif_xdpi = 0.0f;
  TIFFGetField(tif_ctx_.get(), TIFFTAG_XRESOLUTION, &tif_xdpi);
  if (tif_xdpi) {
    pAttribute->x_dpi_ = static_cast<int32_t>(tif_xdpi + 0.5f);
  }

  float tif_ydpi = 0.0f;
  TIFFGetField(tif_ctx_.get(), TIFFTAG_YRESOLUTION, &tif_ydpi);
  if (tif_ydpi) {
    pAttribute->y_dpi_ = static_cast<int32_t>(tif_ydpi + 0.5f);
  }

  FX_SAFE_INT32 checked_width = tif_width;
  FX_SAFE_INT32 checked_height = tif_height;
  if (!checked_width.IsValid() || !checked_height.IsValid()) {
    return false;
  }

  *width = checked_width.ValueOrDie();
  *height = checked_height.ValueOrDie();
  *comps = tif_comps;
  *bpc = tif_bpc;
  if (tif_rps > tif_height) {
    tif_rps = tif_height;
    TIFFSetField(tif_ctx_.get(), TIFFTAG_ROWSPERSTRIP, tif_rps);
  }
  return true;
}

bool CTiffContext::Decode(RetainPtr<CFX_DIBitmap> bitmap) {
  // TODO(crbug.com/355630556): Consider adding support for
  // `FXDIB_Format::kBgraPremul`
  CHECK_EQ(bitmap->GetFormat(), FXDIB_Format::kBgra);
  const uint32_t img_width = bitmap->GetWidth();
  const uint32_t img_height = bitmap->GetHeight();
  uint32_t width = 0;
  uint32_t height = 0;
  TIFFGetField(tif_ctx_.get(), TIFFTAG_IMAGEWIDTH, &width);
  TIFFGetField(tif_ctx_.get(), TIFFTAG_IMAGELENGTH, &height);
  if (img_width != width || img_height != height) {
    return false;
  }

  uint16_t rotation = ORIENTATION_TOPLEFT;
  TIFFGetField(tif_ctx_.get(), TIFFTAG_ORIENTATION, &rotation);
  uint32_t* data =
      fxcrt::reinterpret_span<uint32_t>(bitmap->GetWritableBuffer()).data();
  if (!TIFFReadRGBAImageOriented(tif_ctx_.get(), img_width, img_height, data,
                                 rotation, 1)) {
    return false;
  }

  for (uint32_t row = 0; row < img_height; row++) {
    auto row_span = bitmap->GetWritableScanlineAs<FX_BGRA_STRUCT<uint8_t>>(row);
    for (auto& pixel : row_span) {
      std::swap(pixel.blue, pixel.red);
    }
  }
  return true;
}

namespace fxcodec {

// static
std::unique_ptr<ProgressiveDecoderIface::Context> TiffDecoder::CreateDecoder(
    const RetainPtr<IFX_SeekableReadStream>& file_ptr) {
  auto pDecoder = std::make_unique<CTiffContext>();
  if (!pDecoder->InitDecoder(file_ptr)) {
    return nullptr;
  }

  return pDecoder;
}

// static
bool TiffDecoder::LoadFrameInfo(ProgressiveDecoderIface::Context* pContext,
                                int32_t frame,
                                int32_t* width,
                                int32_t* height,
                                int32_t* comps,
                                int32_t* bpc,
                                CFX_DIBAttribute* pAttribute) {
  DCHECK(pAttribute);

  auto* ctx = static_cast<CTiffContext*>(pContext);
  return ctx->LoadFrameInfo(frame, width, height, comps, bpc, pAttribute);
}

// static
bool TiffDecoder::Decode(ProgressiveDecoderIface::Context* pContext,
                         RetainPtr<CFX_DIBitmap> bitmap) {
  auto* ctx = static_cast<CTiffContext*>(pContext);
  return ctx->Decode(std::move(bitmap));
}

}  // namespace fxcodec
