1// Copyright 2011 Google Inc. 2// 3// Use of this source code is governed by a BSD-style license 4// that can be found in the COPYING file in the root of the source 5// tree. An additional intellectual property rights grant can be found 6// in the file PATENTS. All contributing project authors may 7// be found in the AUTHORS file in the root of the source tree. 8// ----------------------------------------------------------------------------- 9// 10// libwebp swig interface definition 11// 12// Author: James Zern (jzern@google.com) 13 14/* 15 Go bindings: 16 $ swig -go \ 17 -outdir . \ 18 -o libwebp_go_wrap.c libwebp.swig 19 20 Java bindings: 21 $ mkdir -p java/com/google/webp 22 $ swig -java \ 23 -package com.google.webp \ 24 -outdir java/com/google/webp \ 25 -o libwebp_java_wrap.c libwebp.swig 26 27 Python bindings: 28 $ swig -python \ 29 -outdir . \ 30 -o libwebp_python_wrap.c libwebp.swig 31*/ 32 33#ifdef SWIGPYTHON 34%module(package="com.google.webp") libwebp 35#else 36%module libwebp 37#endif /* SWIGPYTHON */ 38 39%include "constraints.i" 40%include "typemaps.i" 41 42#ifdef SWIGGO 43%apply (char* STRING, size_t LENGTH) { (const uint8_t* data, size_t data_size) } 44 45%rename(wrapped_WebPGetInfo) WebPGetInfo(const uint8_t* data, size_t data_size, 46 int* width, int* height); 47#endif /* SWIGGO */ 48 49#ifdef SWIGJAVA 50%include "arrays_java.i"; 51%include "enums.swg" /*NB: requires JDK-1.5+ 52 See: http://www.swig.org/Doc1.3/Java.html#enumerations */ 53 54// map uint8_t* such that a byte[] is used 55%{ 56#include "webp/types.h" 57%} 58// from arrays_java.i (signed char) 59JAVA_ARRAYS_DECL(uint8_t, jbyte, Byte, Uint8) 60JAVA_ARRAYS_IMPL(uint8_t, jbyte, Byte, Uint8) 61JAVA_ARRAYS_TYPEMAPS(uint8_t, byte, jbyte, Uint8, "[B") 62%apply uint8_t[] { uint8_t* } 63#endif /* SWIGJAVA */ 64 65#ifdef SWIGPYTHON 66%apply (char* STRING, size_t LENGTH) { (const uint8_t* data, size_t data_size) } 67%typemap(out) uint8_t* { 68 $result = PyString_FromStringAndSize( 69 (const char*)$1, 70 ($1 == NULL) ? 0 : ReturnedBufferSize("$symname", arg3, arg4)); 71} 72 73%typemap (in) const uint8_t* rgb (Py_buffer rgb_buffer) { 74 // NB: with Python < 2.6 the old style buffer protocol may be used: 75 // Py_ssize_t unused; 76 // PyObject_AsReadBuffer($input, (const void**)(&$1), &unused); 77 if (!PyObject_CheckBuffer($input)) { 78 SWIG_exception_fail(SWIG_TypeError, 79 "in method '$symname', argument $argnum" 80 " does not support the buffer interface"); 81 } 82 if (PyObject_GetBuffer($input, &rgb_buffer, PyBUF_SIMPLE)) { 83 SWIG_exception_fail(SWIG_RuntimeError, 84 "in method '$symname', unable to get buffer view"); 85 } 86 $1 = ($1_ltype)rgb_buffer.buf; 87} 88 89%typemap(freearg) const uint8_t* rgb { 90 PyBuffer_Release(&rgb_buffer$argnum); 91} 92 93%define DECODE_AUTODOC(func) 94%feature("autodoc", #func "(uint8_t data) -> (rgb, width, height)") func; 95%enddef 96 97%feature("autodoc", "1"); 98DECODE_AUTODOC(WebPDecodeRGB); 99DECODE_AUTODOC(WebPDecodeRGBA); 100DECODE_AUTODOC(WebPDecodeARGB); 101DECODE_AUTODOC(WebPDecodeBGR); 102DECODE_AUTODOC(WebPDecodeBGRA); 103%feature("autodoc", "WebPGetInfo(uint8_t data) -> (width, height)") WebPGetInfo; 104#endif /* SWIGPYTHON */ 105 106//------------------------------------------------------------------------------ 107// Decoder specific 108 109%apply int* OUTPUT { int* width, int* height } 110 111int WebPGetDecoderVersion(void); 112int WebPGetInfo(const uint8_t* data, size_t data_size, 113 int* width, int* height); 114 115#if defined(SWIGJAVA) || defined(SWIGPYTHON) 116 117// free the buffer returned by these functions after copying into 118// the native type 119%newobject WebPDecodeRGB; 120%newobject WebPDecodeRGBA; 121%newobject WebPDecodeARGB; 122%newobject WebPDecodeBGR; 123%newobject WebPDecodeBGRA; 124%typemap(newfree) uint8_t* "free($1);" 125 126uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size, 127 int* width, int* height); 128uint8_t* WebPDecodeRGBA(const uint8_t* data, size_t data_size, 129 int* width, int* height); 130uint8_t* WebPDecodeARGB(const uint8_t* data, size_t data_size, 131 int* width, int* height); 132uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size, 133 int* width, int* height); 134uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size, 135 int* width, int* height); 136 137#endif /* SWIGJAVA || SWIGPYTHON */ 138 139//------------------------------------------------------------------------------ 140// Encoder specific 141 142#if defined(SWIGJAVA) || defined(SWIGPYTHON) 143 144int WebPGetEncoderVersion(void); 145 146#endif /* SWIGJAVA || SWIGPYTHON */ 147 148//------------------------------------------------------------------------------ 149// Wrapper code additions 150 151%{ 152#include "webp/decode.h" 153#include "webp/encode.h" 154%} 155 156#ifdef SWIGJAVA 157%{ 158#define FillMeInAsSizeCannotBeDeterminedAutomatically \ 159 (result ? (jint)ReturnedBufferSize(__FUNCTION__, arg3, arg4) : 0) 160%} 161#endif /* SWIGJAVA */ 162 163#if defined(SWIGJAVA) || defined(SWIGPYTHON) 164%{ 165static size_t ReturnedBufferSize( 166 const char* function, int* width, int* height) { 167 static const struct sizemap { 168 const char* function; 169 int size_multiplier; 170 } size_map[] = { 171#ifdef SWIGJAVA 172 { "Java_com_google_webp_libwebpJNI_WebPDecodeRGB", 3 }, 173 { "Java_com_google_webp_libwebpJNI_WebPDecodeRGBA", 4 }, 174 { "Java_com_google_webp_libwebpJNI_WebPDecodeARGB", 4 }, 175 { "Java_com_google_webp_libwebpJNI_WebPDecodeBGR", 3 }, 176 { "Java_com_google_webp_libwebpJNI_WebPDecodeBGRA", 4 }, 177 { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeRGB", 1 }, 178 { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeBGR", 1 }, 179 { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeRGBA", 1 }, 180 { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeBGRA", 1 }, 181 { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessRGB", 1 }, 182 { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessBGR", 1 }, 183 { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessRGBA", 1 }, 184 { "Java_com_google_webp_libwebpJNI_wrap_1WebPEncodeLosslessBGRA", 1 }, 185#endif 186#ifdef SWIGPYTHON 187 { "WebPDecodeRGB", 3 }, 188 { "WebPDecodeRGBA", 4 }, 189 { "WebPDecodeARGB", 4 }, 190 { "WebPDecodeBGR", 3 }, 191 { "WebPDecodeBGRA", 4 }, 192 { "wrap_WebPEncodeRGB", 1 }, 193 { "wrap_WebPEncodeBGR", 1 }, 194 { "wrap_WebPEncodeRGBA", 1 }, 195 { "wrap_WebPEncodeBGRA", 1 }, 196 { "wrap_WebPEncodeLosslessRGB", 1 }, 197 { "wrap_WebPEncodeLosslessBGR", 1 }, 198 { "wrap_WebPEncodeLosslessRGBA", 1 }, 199 { "wrap_WebPEncodeLosslessBGRA", 1 }, 200#endif 201 { NULL, 0 } 202 }; 203 const struct sizemap* p; 204 size_t size = 0; 205 206 for (p = size_map; p->function; ++p) { 207 if (!strcmp(function, p->function)) { 208 size = *width * *height * p->size_multiplier; 209 break; 210 } 211 } 212 213 return size; 214} 215%} 216 217%{ 218typedef size_t (*WebPEncodeFunction)(const uint8_t* rgb, 219 int width, int height, int stride, 220 float quality_factor, uint8_t** output); 221typedef size_t (*WebPEncodeLosslessFunction)(const uint8_t* rgb, 222 int width, int height, int stride, 223 uint8_t** output); 224 225static uint8_t* EncodeLossy(const uint8_t* rgb, 226 int width, int height, int stride, 227 float quality_factor, 228 WebPEncodeFunction encfn, 229 int* output_size, int* unused) { 230 uint8_t* output = NULL; 231 const size_t image_size = 232 encfn(rgb, width, height, stride, quality_factor, &output); 233 // the values of following two will be interpreted by ReturnedBufferSize() 234 // as 'width' and 'height' in the size calculation. 235 *output_size = image_size; 236 *unused = 1; 237 return image_size ? output : NULL; 238} 239 240static uint8_t* EncodeLossless(const uint8_t* rgb, 241 int width, int height, int stride, 242 WebPEncodeLosslessFunction encfn, 243 int* output_size, int* unused) { 244 uint8_t* output = NULL; 245 const size_t image_size = encfn(rgb, width, height, stride, &output); 246 // the values of the following two will be interpreted by 247 // ReturnedBufferSize() as 'width' and 'height' in the size calculation. 248 *output_size = image_size; 249 *unused = 1; 250 return image_size ? output : NULL; 251} 252%} 253 254#endif /* SWIGJAVA || SWIGPYTHON */ 255 256//------------------------------------------------------------------------------ 257// libwebp/encode wrapper functions 258 259#if defined(SWIGJAVA) || defined(SWIGPYTHON) 260 261%apply int* INPUT { int* unused1, int* unused2 } 262%apply int* OUTPUT { int* output_size } 263 264// free the buffer returned by these functions after copying into 265// the native type 266%newobject wrap_WebPEncodeRGB; 267%newobject wrap_WebPEncodeBGR; 268%newobject wrap_WebPEncodeRGBA; 269%newobject wrap_WebPEncodeBGRA; 270%newobject wrap_WebPEncodeLosslessRGB; 271%newobject wrap_WebPEncodeLosslessBGR; 272%newobject wrap_WebPEncodeLosslessRGBA; 273%newobject wrap_WebPEncodeLosslessBGRA; 274 275#ifdef SWIGJAVA 276// There's no reason to call these directly 277%javamethodmodifiers wrap_WebPEncodeRGB "private"; 278%javamethodmodifiers wrap_WebPEncodeBGR "private"; 279%javamethodmodifiers wrap_WebPEncodeRGBA "private"; 280%javamethodmodifiers wrap_WebPEncodeBGRA "private"; 281%javamethodmodifiers wrap_WebPEncodeLosslessRGB "private"; 282%javamethodmodifiers wrap_WebPEncodeLosslessBGR "private"; 283%javamethodmodifiers wrap_WebPEncodeLosslessRGBA "private"; 284%javamethodmodifiers wrap_WebPEncodeLosslessBGRA "private"; 285#endif /* SWIGJAVA */ 286 287#ifdef SWIGPYTHON 288// This autodoc will serve as a catch-all for wrap_*. 289%feature("autodoc", "private, do not call directly."); 290#endif 291 292%inline %{ 293// Changes the return type of WebPEncode* to more closely match Decode*. 294// This also makes it easier to wrap the output buffer in a native type rather 295// than dealing with the return pointer. 296// The additional parameters are to allow reuse of ReturnedBufferSize(), 297// unused2 and output_size will be used in this case. 298#define LOSSY_WRAPPER(FUNC) \ 299 static uint8_t* wrap_##FUNC( \ 300 const uint8_t* rgb, int* unused1, int* unused2, int* output_size, \ 301 int width, int height, int stride, float quality_factor) { \ 302 return EncodeLossy(rgb, width, height, stride, quality_factor, \ 303 FUNC, output_size, unused2); \ 304 } \ 305 306LOSSY_WRAPPER(WebPEncodeRGB) 307LOSSY_WRAPPER(WebPEncodeBGR) 308LOSSY_WRAPPER(WebPEncodeRGBA) 309LOSSY_WRAPPER(WebPEncodeBGRA) 310 311#undef LOSSY_WRAPPER 312 313#define LOSSLESS_WRAPPER(FUNC) \ 314 static uint8_t* wrap_##FUNC( \ 315 const uint8_t* rgb, int* unused1, int* unused2, int* output_size, \ 316 int width, int height, int stride) { \ 317 return EncodeLossless(rgb, width, height, stride, \ 318 FUNC, output_size, unused2); \ 319 } \ 320 321LOSSLESS_WRAPPER(WebPEncodeLosslessRGB) 322LOSSLESS_WRAPPER(WebPEncodeLosslessBGR) 323LOSSLESS_WRAPPER(WebPEncodeLosslessRGBA) 324LOSSLESS_WRAPPER(WebPEncodeLosslessBGRA) 325 326#undef LOSSLESS_WRAPPER 327 328%} 329 330#endif /* SWIGJAVA || SWIGPYTHON */ 331 332//------------------------------------------------------------------------------ 333// Language specific 334 335#ifdef SWIGGO 336%insert(go_wrapper) %{ 337 338// WebPGetInfo has 2 output parameters, provide a version in the more natural 339// go idiom: 340func WebPGetInfo(webp []byte) (ok bool, width int, height int) { 341 w := []int{0} 342 h := []int{0} 343 ok = Wrapped_WebPGetInfo(string(webp), w, h) != 0 344 width = w[0] 345 height = h[0] 346 return 347} 348 349%} 350#endif /* SWIGGO */ 351 352#ifdef SWIGJAVA 353%{ 354/* Work around broken gcj jni.h */ 355#ifdef __GCJ_JNI_H__ 356# undef JNIEXPORT 357# define JNIEXPORT 358# undef JNICALL 359# define JNICALL 360#endif 361%} 362 363%pragma(java) modulecode=%{ 364 private static final int UNUSED = 1; 365 private static int outputSize[] = { 0 }; 366%} 367 368 369%define CALL_ENCODE_LOSSY_WRAPPER(func) 370%pragma(java) modulecode=%{ 371 public static byte[] func( 372 byte[] rgb, int width, int height, int stride, float quality_factor) { 373 return wrap_##func( 374 rgb, UNUSED, UNUSED, outputSize, width, height, stride, quality_factor); 375 } 376%} 377%enddef 378 379%define CALL_ENCODE_LOSSLESS_WRAPPER(func) 380%pragma(java) modulecode=%{ 381 public static byte[] func( 382 byte[] rgb, int width, int height, int stride) { 383 return wrap_##func( 384 rgb, UNUSED, UNUSED, outputSize, width, height, stride); 385 } 386%} 387%enddef 388 389CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeRGB) 390CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeRGBA) 391CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeBGR) 392CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeBGRA) 393CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessRGB) 394CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessRGBA) 395CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessBGR) 396CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessBGRA) 397#endif /* SWIGJAVA */ 398 399#ifdef SWIGPYTHON 400%pythoncode %{ 401_UNUSED = 1 402%} 403 404%define CALL_ENCODE_LOSSY_WRAPPER(func) 405%pythoncode %{ 406def func(rgb, width, height, stride, quality_factor): 407 """func(uint8_t rgb, int width, int height, int stride, float quality_factor) -> lossy_webp""" 408 webp = wrap_##func( 409 rgb, _UNUSED, _UNUSED, width, height, stride, quality_factor) 410 if len(webp[0]) == 0: 411 return None 412 return webp[0] 413%} 414%enddef 415 416%define CALL_ENCODE_LOSSLESS_WRAPPER(func) 417%pythoncode %{ 418def func(rgb, width, height, stride): 419 """func(uint8_t rgb, int width, int height, int stride) -> lossless_webp""" 420 webp = wrap_##func(rgb, _UNUSED, _UNUSED, width, height, stride) 421 if len(webp[0]) == 0: 422 return None 423 return webp[0] 424%} 425%enddef 426 427CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeRGB) 428CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeRGBA) 429CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeBGR) 430CALL_ENCODE_LOSSY_WRAPPER(WebPEncodeBGRA) 431CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessRGB) 432CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessRGBA) 433CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessBGR) 434CALL_ENCODE_LOSSLESS_WRAPPER(WebPEncodeLosslessBGRA) 435#endif /* SWIGPYTHON */ 436