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