// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// -----------------------------------------------------------------------------
//
//  Libwp2 SWIG interface definition.
//
// Author: Yannis Guyon (yguyon@google.com)

%module libwebp2

%{
#include "imageio/anim_image_dec.h"
#include "imageio/image_enc.h"
#include "imageio/image_dec.h"
#include "imageio/imageio_util.h"
#include "src/wp2/base.h"
#include "src/wp2/decode.h"
#include "src/wp2/encode.h"
%}

//------------------------------------------------------------------------------
// Typemaps

%include "stdint.i"
%include "typemaps.i"

// Maps uint8_t array and target language bytes structure.
#ifdef SWIGPYTHON
// Python bytes to C array.
%typemap(in) (const uint8_t* input_data, size_t input_data_size) {
  $1 = (uint8_t*)PyBytes_AsString($input);
  $2 = PyBytes_Size($input);
}

// C array to Python bytes.
%typemap(in, numinputs=0)
    (const uint8_t** output_data, size_t* output_data_size)
    (uint8_t* temp_output_data, size_t temp_output_data_size) {
  temp_output_data = nullptr;
  $1 = &temp_output_data;
  temp_output_data_size = 0;
  $2 = &temp_output_data_size;
}
%typemap(argout) (const uint8_t** output_data, size_t* output_data_size) {
  Py_XDECREF($result);
  $result = PyBytes_FromStringAndSize((const char*)*$1,
                                      (*$1 == nullptr) ? 0 : *$2);
}
#endif  // SWIGPYTHON

// Raises an exception when a function returns a bad WP2Status.
%typemap(out) WP2Status %{
  if ($1 != WP2_STATUS_OK) {
    SWIG_exception_fail(SWIG_RuntimeError,
        ("$name returned error " + std::to_string($1) + ": " +
         WP2GetStatusText($1)).c_str());
  }
  resultobj = SWIG_From_int(static_cast<int>(result));
%}

//------------------------------------------------------------------------------
// Base

extern int WP2GetVersion();
extern int WP2GetABIVersion();
extern bool WP2CheckVersion();

typedef enum {
  WP2_STATUS_OK = 0,
  WP2_STATUS_VERSION_MISMATCH,
  WP2_STATUS_OUT_OF_MEMORY,
  WP2_STATUS_INVALID_PARAMETER,
  WP2_STATUS_NULL_PARAMETER,
  WP2_STATUS_BAD_DIMENSION,
  WP2_STATUS_USER_ABORT,
  WP2_STATUS_UNSUPPORTED_FEATURE,
  WP2_STATUS_BITSTREAM_ERROR,
  WP2_STATUS_NOT_ENOUGH_DATA,
  WP2_STATUS_BAD_READ,
  WP2_STATUS_NEURAL_DECODE_FAILURE,
  WP2_STATUS_BITSTREAM_OUT_OF_MEMORY,
  WP2_STATUS_INVALID_CONFIGURATION,
  WP2_STATUS_BAD_WRITE,
  WP2_STATUS_FILE_TOO_BIG,
  WP2_STATUS_INVALID_COLORSPACE,
  WP2_STATUS_NEURAL_ENCODE_FAILURE
} WP2Status;

extern const char* WP2GetStatusText(WP2Status status);

typedef enum {
  WP2_Argb_32, WP2_ARGB_32, WP2_XRGB_32,
  WP2_rgbA_32, WP2_RGBA_32, WP2_RGBX_32,
  WP2_bgrA_32, WP2_BGRA_32, WP2_BGRX_32,
  WP2_RGB_24, WP2_BGR_24
} WP2SampleFormat;

namespace WP2 {

struct Rectangle {
  uint32_t x, y, width, height;
};

//------------------------------------------------------------------------------
// Reading

class ArgbBuffer {
 public:
  ArgbBuffer(WP2SampleFormat format_in = WP2_Argb_32);
  bool IsEmpty() const;
  void* GetRow(uint32_t y);
  WP2Status CopyFrom(const ArgbBuffer& src);
  WP2Status ConvertFrom(const ArgbBuffer& src);
  WP2SampleFormat format() const;
  uint32_t width() const;
  uint32_t height() const;
  uint32_t stride() const;
};

// Gets a pointer to data.
%extend ArgbBuffer {
void GetBytes(const uint8_t** output_data, size_t* const output_data_size) {
  if ((output_data != nullptr) && (output_data_size != nullptr)) {
    *output_data = (uint8_t*)$self->GetRow(0);
    *output_data_size = $self->height() * $self->stride();
  }
}
};

WP2Status ReadImage(const char* file_path, ArgbBuffer* buffer,
                    size_t* file_size = nullptr);

%apply bool* OUTPUT { bool* const is_last };
%apply uint32_t* OUTPUT { uint32_t* const duration_ms };
class ImageReader {
 public:
  ImageReader(const char* const file_path, ArgbBuffer* const buffer);

  static constexpr uint32_t kInfiniteDuration = 0;
  WP2Status ReadFrame(bool* const is_last, uint32_t* const duration_ms);
};

//------------------------------------------------------------------------------
// Writing

WP2Status IoUtilWriteFile(const uint8_t* data, size_t data_size,
                          const char* const file_name, bool overwrite);
WP2Status SaveImage(const ArgbBuffer& buffer, const char* const file_path,
                    bool overwrite = false);

//------------------------------------------------------------------------------
// Encoding

class MemoryWriter {
 public:
  uint8_t* mem_;
  size_t size_;
};

// Gets a pointer to data.
%extend MemoryWriter {
void GetBytes(const uint8_t** output_data, size_t* const output_data_size) {
  if ((output_data != nullptr) && (output_data_size != nullptr)) {
    *output_data = $self->mem_;
    *output_data_size = $self->size_;
  }
}
};

struct EncoderConfig {
  float quality;
  int effort;
  int thread_level;

  bool IsValid() const;
};

WP2Status Encode(const ArgbBuffer& input, MemoryWriter* output,
                 const EncoderConfig& config);

class AnimationEncoder {
 public:
  WP2Status AddFrame(const ArgbBuffer& Argb, uint32_t duration_ms,
                     bool force_dispose = false);
  WP2Status Encode(MemoryWriter* memory_writer,
                   const EncoderConfig& config) const;
};

//------------------------------------------------------------------------------
// Decoding

struct BitstreamFeatures {
  uint32_t width;
  uint32_t height;
  int is_animation;
  int has_preview;
  int has_icc;
  int has_trailing_data;
  bool loop_forever;
  size_t header_size;
};

struct FrameFeatures {
  uint32_t duration_ms;
  Rectangle window;
  bool is_last;
  uint32_t last_dispose_frame_index;
};

WP2Status Decode(const uint8_t* input_data, size_t input_data_size,
                 ArgbBuffer* output_buffer);

class Decoder {
 public:
  bool ReadFrame();
  WP2Status GetStatus() const;
  bool Failed() const;
  const BitstreamFeatures* TryGetDecodedFeatures() const;
  const FrameFeatures* TryGetFrameDecodedFeatures(uint32_t frame_index) const;
  bool TryGetFrameLocation(uint32_t frame_index, size_t* offset,
                           size_t* length = nullptr) const;
  uint32_t GetCurrentFrameIndex() const;
  uint32_t GetNumFrameDecodedFeatures() const;
  Rectangle GetDecodedArea() const;
  const ArgbBuffer& GetPixels() const;
 protected:
  Decoder();
};

// Simple language-independant interface to access frame duration.
%extend Decoder {
  int GetFrameDurationMs() const {
    const WP2::FrameFeatures* current_frame_features =
        $self->TryGetFrameDecodedFeatures($self->GetCurrentFrameIndex());
    if (current_frame_features != nullptr) {
      return (int)current_frame_features->duration_ms;
    }
    return -1;
  }
};

class ArrayDecoder : public Decoder {
 public:
  ArrayDecoder();
  void SetInput(const uint8_t* input_data, size_t input_data_size);
};

class StreamDecoder : public Decoder {
 public:
  StreamDecoder();
  void AppendInput(const uint8_t* input_data, size_t input_data_size);
};

//------------------------------------------------------------------------------

}
