blob: 6f70a161d52a8fa276e121f30c48ddae03c2472a [file] [log] [blame]
// 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);
};
//------------------------------------------------------------------------------
}