libwebp/swig/libwebp.i
James Zern a5c297c842 swig/java: reduce wrapper function code duplication
define a macro to emit the wrapper code

Change-Id: I672416016162d6d9ce6f455d224044e0837e3ace
2013-05-20 17:13:27 -07:00

308 lines
10 KiB
OpenEdge ABL

// Copyright 2011 Google Inc.
//
// This code is licensed under the same terms as WebM:
// Software License Agreement: http://www.webmproject.org/license/software/
// Additional IP Rights Grant: http://www.webmproject.org/license/additional/
// -----------------------------------------------------------------------------
//
// libwebp swig interface definition
//
// Author: James Zern (jzern@google.com)
/*
Java bindings:
$ mkdir -p java/com/google/webp
$ swig -java \
-package com.google.webp \
-outdir java/com/google/webp \
-o libwebp_java_wrap.c libwebp.i
Python bindings:
$ swig -python \
-outdir . \
-o libwebp_python_wrap.c libwebp.i
*/
#ifdef SWIGPYTHON
%module(package="com.google.webp") libwebp
#else
%module libwebp
#endif /* SWIGPYTHON */
%include "constraints.i"
%include "typemaps.i"
#ifdef SWIGJAVA
%include "arrays_java.i";
%include "enums.swg" /*NB: requires JDK-1.5+
See: http://www.swig.org/Doc1.3/Java.html#enumerations */
// map uint8_t* such that a byte[] is used
%{
#include "webp/types.h"
%}
// from arrays_java.i (signed char)
JAVA_ARRAYS_DECL(uint8_t, jbyte, Byte, Uint8)
JAVA_ARRAYS_IMPL(uint8_t, jbyte, Byte, Uint8)
JAVA_ARRAYS_TYPEMAPS(uint8_t, byte, jbyte, Uint8, "[B")
%apply uint8_t[] { uint8_t* }
#endif /* SWIGJAVA */
#ifdef SWIGPYTHON
%apply (char* STRING, size_t LENGTH) { (const uint8_t* data, size_t data_size) }
%typemap(out) uint8_t* {
$result = PyString_FromStringAndSize(
(const char*)$1, ReturnedBufferSize("$symname", arg3, arg4));
}
#endif /* SWIGPYTHON */
//------------------------------------------------------------------------------
// Decoder specific
%apply int* OUTPUT { int* width, int* height }
// free the buffer returned by these functions after copying into
// the native type
%newobject WebPDecodeRGB;
%newobject WebPDecodeRGBA;
%newobject WebPDecodeARGB;
%newobject WebPDecodeBGR;
%newobject WebPDecodeBGRA;
%typemap(newfree) uint8_t* "free($1);"
int WebPGetDecoderVersion(void);
int WebPGetInfo(const uint8_t* data, size_t data_size,
int* width, int* height);
uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size,
int* width, int* height);
uint8_t* WebPDecodeRGBA(const uint8_t* data, size_t data_size,
int* width, int* height);
uint8_t* WebPDecodeARGB(const uint8_t* data, size_t data_size,
int* width, int* height);
uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size,
int* width, int* height);
uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size,
int* width, int* height);
//------------------------------------------------------------------------------
// Encoder specific
int WebPGetEncoderVersion(void);
//------------------------------------------------------------------------------
// Wrapper code additions
%{
#include "webp/decode.h"
#include "webp/encode.h"
%}
#ifdef SWIGJAVA
%{
#define FillMeInAsSizeCannotBeDeterminedAutomatically \
(result ? (jint)ReturnedBufferSize(__FUNCTION__, arg3, arg4) : 0)
%}
#endif /* SWIGJAVA */
#if defined(SWIGJAVA) || defined(SWIGPYTHON)
%{
static size_t ReturnedBufferSize(
const char* function, int* width, int* height) {
static const struct sizemap {
const char* function;
int size_multiplier;
} size_map[] = {
#ifdef SWIGJAVA
{ "Java_com_google_webp_libwebpJNI_WebPDecodeRGB", 3 },
{ "Java_com_google_webp_libwebpJNI_WebPDecodeRGBA", 4 },
{ "Java_com_google_webp_libwebpJNI_WebPDecodeARGB", 4 },
{ "Java_com_google_webp_libwebpJNI_WebPDecodeBGR", 3 },
{ "Java_com_google_webp_libwebpJNI_WebPDecodeBGRA", 4 },
{ "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeRGB", 1 },
{ "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeBGR", 1 },
{ "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeRGBA", 1 },
{ "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeBGRA", 1 },
{ "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessRGB", 1 },
{ "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessBGR", 1 },
{ "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessRGBA", 1 },
{ "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessBGRA", 1 },
#endif
#ifdef SWIGPYTHON
{ "WebPDecodeRGB", 3 },
{ "WebPDecodeRGBA", 4 },
{ "WebPDecodeARGB", 4 },
{ "WebPDecodeBGR", 3 },
{ "WebPDecodeBGRA", 4 },
#endif
{ NULL, 0 }
};
const struct sizemap* p;
size_t size = 0;
for (p = size_map; p->function; ++p) {
if (!strcmp(function, p->function)) {
size = *width * *height * p->size_multiplier;
break;
}
}
return size;
}
%}
#endif /* SWIGJAVA || SWIGPYTHON */
%{
typedef size_t (*WebPEncodeFunction)(const uint8_t* rgb,
int width, int height, int stride,
float quality_factor, uint8_t** output);
typedef size_t (*WebPEncodeLosslessFunction)(const uint8_t* rgb,
int width, int height, int stride,
uint8_t** output);
static uint8_t* EncodeLossy(const uint8_t* rgb,
int width, int height, int stride,
float quality_factor,
WebPEncodeFunction encfn,
int* output_size, int* unused) {
uint8_t* output = NULL;
const size_t image_size =
encfn(rgb, width, height, stride, quality_factor, &output);
// the values of following two will be interpreted by ReturnedBufferSize()
// as 'width' and 'height' in the size calculation.
*output_size = image_size;
*unused = 1;
return image_size ? output : NULL;
}
static uint8_t* EncodeLossless(const uint8_t* rgb,
int width, int height, int stride,
WebPEncodeLosslessFunction encfn,
int* output_size, int* unused) {
uint8_t* output = NULL;
const size_t image_size = encfn(rgb, width, height, stride, &output);
// the values of the following two will be interpreted by
// ReturnedBufferSize() as 'width' and 'height' in the size calculation.
*output_size = image_size;
*unused = 1;
return image_size ? output : NULL;
}
%}
//------------------------------------------------------------------------------
// libwebp/encode wrapper functions
%apply int* INPUT { int* unused1, int* unused2 }
%apply int* OUTPUT { int* output_size }
// free the buffer returned by these functions after copying into
// the native type
%newobject wrap_WebPEncodeRGB;
%newobject wrap_WebPEncodeBGR;
%newobject wrap_WebPEncodeRGBA;
%newobject wrap_WebPEncodeBGRA;
%newobject wrap_WebPEncodeLosslessRGB;
%newobject wrap_WebPEncodeLosslessBGR;
%newobject wrap_WebPEncodeLosslessRGBA;
%newobject wrap_WebPEncodeLosslessBGRA;
#ifdef SWIGJAVA
// There's no reason to call these directly
%javamethodmodifiers wrap_WebPEncodeRGB "private";
%javamethodmodifiers wrap_WebPEncodeBGR "private";
%javamethodmodifiers wrap_WebPEncodeRGBA "private";
%javamethodmodifiers wrap_WebPEncodeBGRA "private";
%javamethodmodifiers wrap_WebPEncodeLosslessRGB "private";
%javamethodmodifiers wrap_WebPEncodeLosslessBGR "private";
%javamethodmodifiers wrap_WebPEncodeLosslessRGBA "private";
%javamethodmodifiers wrap_WebPEncodeLosslessBGRA "private";
#endif /* SWIGJAVA */
%inline %{
// Changes the return type of WebPEncode* to more closely match Decode*.
// This also makes it easier to wrap the output buffer in a native type rather
// than dealing with the return pointer.
// The additional parameters are to allow reuse of ReturnedBufferSize(),
// unused2 and output_size will be used in this case.
#define LOSSY_WRAPPER(FUNC) \
static uint8_t* wrap_##FUNC( \
const uint8_t* rgb, int* unused1, int* unused2, int* output_size, \
int width, int height, int stride, float quality_factor) { \
return EncodeLossy(rgb, width, height, stride, quality_factor, \
FUNC, output_size, unused2); \
} \
LOSSY_WRAPPER(WebPEncodeRGB)
LOSSY_WRAPPER(WebPEncodeBGR)
LOSSY_WRAPPER(WebPEncodeRGBA)
LOSSY_WRAPPER(WebPEncodeBGRA)
#undef LOSSY_WRAPPER
#define LOSSLESS_WRAPPER(FUNC) \
static uint8_t* wrap_##FUNC( \
const uint8_t* rgb, int* unused1, int* unused2, int* output_size, \
int width, int height, int stride) { \
return EncodeLossless(rgb, width, height, stride, \
FUNC, output_size, unused2); \
} \
LOSSLESS_WRAPPER(WebPEncodeLosslessRGB)
LOSSLESS_WRAPPER(WebPEncodeLosslessBGR)
LOSSLESS_WRAPPER(WebPEncodeLosslessRGBA)
LOSSLESS_WRAPPER(WebPEncodeLosslessBGRA)
#undef LOSSLESS_WRAPPER
%}
//------------------------------------------------------------------------------
// Language specific
#ifdef SWIGJAVA
%{
/* Work around broken gcj jni.h */
#ifdef __GCJ_JNI_H__
# undef JNIEXPORT
# define JNIEXPORT
# undef JNICALL
# define JNICALL
#endif
%}
%pragma(java) modulecode=%{
private static final int UNUSED = 1;
private static int outputSize[] = { 0 };
%}
%define CALL_ENCODE_LOSSY_WRAPPER(func)
%pragma(java) modulecode=%{
public static byte[] func(
byte[] rgb, int width, int height, int stride, float quality_factor) {
return wrap_##func(
rgb, UNUSED, UNUSED, outputSize, width, height, stride, quality_factor);
}
%}
%enddef
%define CALL_ENCODE_LOSSLESS_WRAPPER(func)
%pragma(java) modulecode=%{
public static byte[] func(
byte[] rgb, int width, int height, int stride) {
return wrap_##func(
rgb, UNUSED, UNUSED, outputSize, width, height, stride);
}
%}
%enddef
CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeRGB)
CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeRGBA)
CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeBGR)
CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeBGRA)
CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessRGB)
CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessRGBA)
CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessBGR)
CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessBGRA)
#endif /* SWIGJAVA */