// Copyright 2023 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "core/fxge/dib/cfx_dibbase.h"

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <type_traits>
#include <utility>

#include "core/fxcrt/fx_2d_size.h"
#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/fx_memory_wrappers.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxge/calculate_pitch.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "core/fxge/dib/fx_dib.h"
#include "third_party/base/check_op.h"
#include "third_party/base/notreached.h"
#include "third_party/base/span.h"
#include "third_party/skia/include/core/SkAlphaType.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkColorPriv.h"
#include "third_party/skia/include/core/SkColorType.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkPixmap.h"
#include "third_party/skia/include/core/SkRefCnt.h"

namespace {

// Releases `CFX_DIBBase` "leaked" by `CreateSkiaImageFromDib()`.
void ReleaseRetainedHeldBySkImage(const void* /*pixels*/,
                                  SkImages::ReleaseContext context) {
  RetainPtr<const CFX_DIBBase> retained;
  retained.Unleak(reinterpret_cast<const CFX_DIBBase*>(context));
}

// Creates an `SkImage` from a `CFX_DIBBase`, sharing the underlying pixels if
// possible.
//
// Note that an `SkImage` must be immutable, so if sharing pixels, they must not
// be modified during the lifetime of the `SkImage`.
sk_sp<SkImage> CreateSkiaImageFromDib(const CFX_DIBBase* source,
                                      SkColorType color_type) {
  // Make sure the DIB is backed by a buffer.
  RetainPtr<const CFX_DIBBase> retained;
  if (source->GetBuffer().empty()) {
    retained = source->Realize();
    if (!retained) {
      return nullptr;
    }
    DCHECK(!source->GetBuffer().empty());
  } else {
    retained.Reset(source);
  }

  // Convert unowned pointer to a retained pointer, then "leak" to `SkImage`.
  source = retained.Leak();
  SkImageInfo info = SkImageInfo::Make(source->GetWidth(), source->GetHeight(),
                                       color_type, kPremul_SkAlphaType);
  return SkImages::RasterFromPixmap(
      SkPixmap(info, source->GetBuffer().data(), source->GetPitch()),
      /*rasterReleaseProc=*/ReleaseRetainedHeldBySkImage,
      /*releaseContext=*/const_cast<CFX_DIBBase*>(source));
}

// Releases allocated memory "leaked" by `CreateSkiaImageFromTransformedDib()`.
void ReleaseAllocatedHeldBySkImage(const void* pixels,
                                   SkImages::ReleaseContext /*context*/) {
  FX_Free(const_cast<void*>(pixels));
}

// Template defining traits of a pixel transform function.
template <size_t source_bits_per_pixel, typename PixelTransform>
class PixelTransformTraits;

template <typename PixelTransform>
class PixelTransformTraits<1, PixelTransform> {
 public:
  using Result = std::invoke_result_t<PixelTransform, bool>;

  static Result Invoke(PixelTransform&& pixel_transform,
                       const uint8_t* scanline,
                       size_t column) {
    uint8_t kMask = 1 << (7 - column % 8);
    return pixel_transform(!!(scanline[column / 8] & kMask));
  }
};

template <typename PixelTransform>
class PixelTransformTraits<8, PixelTransform> {
 public:
  using Result = std::invoke_result_t<PixelTransform, uint8_t>;

  static Result Invoke(PixelTransform&& pixel_transform,
                       const uint8_t* scanline,
                       size_t column) {
    return pixel_transform(scanline[column]);
  }
};

template <typename PixelTransform>
class PixelTransformTraits<24, PixelTransform> {
 public:
  using Result =
      std::invoke_result_t<PixelTransform, uint8_t, uint8_t, uint8_t>;

  static Result Invoke(PixelTransform&& pixel_transform,
                       const uint8_t* scanline,
                       size_t column) {
    size_t offset = column * 3;
    return pixel_transform(scanline[offset + 2], scanline[offset + 1],
                           scanline[offset]);
  }
};

void ValidateScanlineSize(pdfium::span<const uint8_t> scanline,
                          size_t min_row_bytes) {
  DCHECK_GE(scanline.size(), min_row_bytes);
}

void ValidateBufferSize(pdfium::span<const uint8_t> buffer,
                        const CFX_DIBBase& source) {
#if DCHECK_IS_ON()
  if (source.GetHeight() == 0) {
    return;
  }

  FX_SAFE_SIZE_T buffer_size = source.GetHeight() - 1;
  buffer_size *= source.GetPitch();
  buffer_size += fxge::CalculatePitch8OrDie(source.GetBPP(), /*components=*/1,
                                            source.GetWidth());

  DCHECK_GE(buffer.size(), buffer_size.ValueOrDie());
#endif  // DCHECK_IS_ON()
}

// Creates an `SkImage` from a `CFX_DIBBase`, transforming the source pixels
// using `pixel_transform`.
template <size_t source_bits_per_pixel, typename PixelTransform>
sk_sp<SkImage> CreateSkiaImageFromTransformedDib(
    const CFX_DIBBase& source,
    SkColorType color_type,
    SkAlphaType alpha_type,
    PixelTransform&& pixel_transform) {
  using Traits = PixelTransformTraits<source_bits_per_pixel, PixelTransform>;
  using Result = typename Traits::Result;

  // Allocate output buffer.
  const int width = source.GetWidth();
  const int height = source.GetHeight();
  SkImageInfo info = SkImageInfo::Make(width, height, color_type, alpha_type);
  DCHECK_EQ(info.minRowBytes(), width * sizeof(Result));

  size_t output_size = Fx2DSizeOrDie(info.minRowBytes(), height);
  std::unique_ptr<void, FxFreeDeleter> output(
      FX_TryAlloc(uint8_t, output_size));
  if (!output) {
    return nullptr;
  }

  // Transform source pixels to output pixels.
  pdfium::span<const uint8_t> source_buffer = source.GetBuffer();
  Result* output_cursor = reinterpret_cast<Result*>(output.get());
  if (source_buffer.empty()) {
    // No buffer; iterate by individual scanline.
    const size_t min_row_bytes =
        fxge::CalculatePitch8OrDie(source.GetBPP(), /*components=*/1, width);
    DCHECK_LE(min_row_bytes, source.GetPitch());

    int line = 0;
    for (int row = 0; row < height; ++row) {
      pdfium::span<const uint8_t> scanline = source.GetScanline(line++);
      ValidateScanlineSize(scanline, min_row_bytes);

      for (int column = 0; column < width; ++column) {
        *output_cursor++ =
            Traits::Invoke(std::forward<PixelTransform>(pixel_transform),
                           scanline.data(), column);
      }
    }
  } else {
    // Iterate over the entire buffer.
    ValidateBufferSize(source_buffer, source);
    const size_t row_bytes = source.GetPitch();

    const uint8_t* next_scanline = source_buffer.data();
    for (int row = 0; row < height; ++row) {
      const uint8_t* scanline = next_scanline;
      next_scanline += row_bytes;

      for (int column = 0; column < width; ++column) {
        *output_cursor++ = Traits::Invoke(
            std::forward<PixelTransform>(pixel_transform), scanline, column);
      }
    }
  }

  // "Leak" allocated memory to `SkImage`.
  return SkImages::RasterFromPixmap(
      SkPixmap(info, output.release(), info.minRowBytes()),
      /*rasterReleaseProc=*/ReleaseAllocatedHeldBySkImage,
      /*releaseContext=*/nullptr);
}

bool IsRGBColorGrayScale(uint32_t color) {
  return FXARGB_R(color) == FXARGB_G(color) &&
         FXARGB_R(color) == FXARGB_B(color);
}

}  // namespace

sk_sp<SkImage> CFX_DIBBase::RealizeSkImage(bool force_alpha) const {
  const SkColorType color_type = force_alpha || IsMaskFormat()
                                     ? SkColorType::kAlpha_8_SkColorType
                                     : SkColorType::kGray_8_SkColorType;
  switch (GetBPP()) {
    case 1: {
      // By default, the two colors for grayscale are 0xFF and 0x00 unless they
      // are specified in the palette.
      uint8_t color0 = 0x00;
      uint8_t color1 = 0xFF;

      if (GetFormat() == FXDIB_Format::k1bppRgb && HasPalette()) {
        uint32_t palette_color0 = GetPaletteArgb(0);
        uint32_t palette_color1 = GetPaletteArgb(1);
        bool use_gray_colors = IsRGBColorGrayScale(palette_color0) &&
                               IsRGBColorGrayScale(palette_color1);
        if (!use_gray_colors) {
          return CreateSkiaImageFromTransformedDib</*source_bits_per_pixel=*/1>(
              *this, kBGRA_8888_SkColorType, kPremul_SkAlphaType,
              [palette_color0, palette_color1](bool bit) {
                return bit ? palette_color1 : palette_color0;
              });
        }

        color0 = FXARGB_R(palette_color0);
        color1 = FXARGB_R(palette_color1);
      }

      return CreateSkiaImageFromTransformedDib</*source_bits_per_pixel=*/1>(
          *this, color_type, kPremul_SkAlphaType,
          [color0, color1](bool bit) { return bit ? color1 : color0; });
    }

    case 8:
      // we upscale ctables to 32bit.
      if (HasPalette()) {
        return CreateSkiaImageFromTransformedDib</*source_bits_per_pixel=*/8>(
            *this, kBGRA_8888_SkColorType, kPremul_SkAlphaType,
            [palette = GetPaletteSpan().first(GetRequiredPaletteSize())](
                uint8_t index) {
              if (index >= palette.size()) {
                index = 0;
              }
              return palette[index];
            });
      }
      return CreateSkiaImageFromDib(this, color_type);

    case 24:
      return CreateSkiaImageFromTransformedDib</*source_bits_per_pixel=*/24>(
          *this, kBGRA_8888_SkColorType, kOpaque_SkAlphaType,
          [](uint8_t red, uint8_t green, uint8_t blue) {
            return SkPackARGB32NoCheck(0xFF, red, green, blue);
          });

    case 32:
      return CreateSkiaImageFromDib(this, kBGRA_8888_SkColorType);

    default:
      NOTREACHED_NORETURN();
  }
}
