naev 0.12.6
nlua_data.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <lauxlib.h>
12
13#include "nlua_data.h"
14
15#include "nluadef.h"
16
17/* Helper functions. */
18static size_t dataL_checkpos( lua_State *L, const LuaData_t *ld, long pos );
19
20/* Data metatable methods. */
21static int dataL_gc( lua_State *L );
22static int dataL_eq( lua_State *L );
23static int dataL_new( lua_State *L );
24static int dataL_get( lua_State *L );
25static int dataL_set( lua_State *L );
26static int dataL_getSize( lua_State *L );
27static int dataL_getString( lua_State *L );
28static int dataL_paste( lua_State *L );
29static int dataL_addWeighted( lua_State *L );
30static int dataL_convolve2d( lua_State *L );
31
32static const luaL_Reg dataL_methods[] = {
33 { "__gc", dataL_gc },
34 { "__eq", dataL_eq },
35 { "new", dataL_new },
36 { "get", dataL_get },
37 { "set", dataL_set },
38 { "getSize", dataL_getSize },
39 { "getString", dataL_getString },
40 { "paste", dataL_paste },
41 { "addWeighted", dataL_addWeighted },
42 { "convolve2d", dataL_convolve2d },
43 { 0, 0 } };
44
51int nlua_loadData( nlua_env env )
52{
53 nlua_register( env, DATA_METATABLE, dataL_methods, 1 );
54 return 0;
55}
56
69LuaData_t *lua_todata( lua_State *L, int ind )
70{
71 return (LuaData_t *)lua_touserdata( L, ind );
72}
73
80LuaData_t *luaL_checkdata( lua_State *L, int ind )
81{
82 if ( lua_isdata( L, ind ) )
83 return lua_todata( L, ind );
84 luaL_typerror( L, ind, DATA_METATABLE );
85 return NULL;
86}
87
94LuaData_t *lua_pushdata( lua_State *L, LuaData_t data )
95{
96 LuaData_t *c;
97 c = (LuaData_t *)lua_newuserdata( L, sizeof( LuaData_t ) );
98 *c = data;
99 luaL_getmetatable( L, DATA_METATABLE );
100 lua_setmetatable( L, -2 );
101 return c;
102}
103
110int lua_isdata( lua_State *L, int ind )
111{
112 int ret;
113
114 if ( lua_getmetatable( L, ind ) == 0 )
115 return 0;
116 lua_getfield( L, LUA_REGISTRYINDEX, DATA_METATABLE );
117
118 ret = 0;
119 if ( lua_rawequal( L, -1, -2 ) ) /* does it have the correct mt? */
120 ret = 1;
121
122 lua_pop( L, 2 ); /* remove both metatables */
123 return ret;
124}
125
132static int dataL_gc( lua_State *L )
133{
134 LuaData_t *ld = luaL_checkdata( L, 1 );
135 free( ld->data );
136 return 0;
137}
138
147static int dataL_eq( lua_State *L )
148{
149 LuaData_t *d1, *d2;
150 d1 = luaL_checkdata( L, 1 );
151 d2 = luaL_checkdata( L, 2 );
152 if ( d1->size != d2->size ) {
153 lua_pushboolean( L, 0 );
154 return 1;
155 }
156 lua_pushboolean( L, ( memcmp( d1->data, d2->data, d1->size ) == 0 ) );
157 return 1;
158}
159
168static int dataL_new( lua_State *L )
169{
170 LuaData_t ld;
171 size_t size = luaL_checklong( L, 1 );
172 const char *type = luaL_checkstring( L, 2 );
173 if ( strcmp( type, "number" ) == 0 ) {
174 ld.type = LUADATA_NUMBER;
175 ld.elem = sizeof( float );
176 } else
177 return NLUA_ERROR( L, _( "unknown data type '%s'" ), type );
178 ld.size = size * ld.elem;
179 ld.data = calloc( ld.elem, size );
180 lua_pushdata( L, ld );
181 return 1;
182}
183
184static size_t dataL_checkpos( lua_State *L, const LuaData_t *ld, long pos )
185{
186 size_t mpos;
187 if ( pos < 0 )
188 return NLUA_ERROR( L, _( "position argument must be positive!" ) );
189 mpos = pos * ld->elem;
190 if ( mpos >= ld->size )
191 return NLUA_ERROR(
192 L, _( "position argument out of bounds: %d of %d elements" ), pos,
193 ld->size / ld->elem );
194 return mpos;
195}
196
205static int dataL_get( lua_State *L )
206{
207 LuaData_t *ld = luaL_checkdata( L, 1 );
208 long pos = luaL_checklong( L, 2 );
209 size_t mpos = dataL_checkpos( L, ld, pos );
210 char *data = ld->data;
211 switch ( ld->type ) {
212 case LUADATA_NUMBER:
213 lua_pushnumber( L, *( (float *)( (void *)&data[mpos] ) ) );
214 break;
215 }
216 return 1;
217}
218
227static int dataL_set( lua_State *L )
228{
229 LuaData_t *ld = luaL_checkdata( L, 1 );
230 long pos = luaL_checklong( L, 2 );
231 size_t mpos = dataL_checkpos( L, ld, pos );
232 char *data = ld->data;
233 double value;
234 switch ( ld->type ) {
235 case LUADATA_NUMBER:
236 value = luaL_checknumber( L, 3 );
237 *( (float *)( (void *)&data[mpos] ) ) = value;
238 break;
239 }
240 return 0;
241}
242
250static int dataL_getSize( lua_State *L )
251{
252 LuaData_t *ld = luaL_checkdata( L, 1 );
253 lua_pushnumber( L, ld->size );
254 return 1;
255}
256
264static int dataL_getString( lua_State *L )
265{
266 LuaData_t *ld = luaL_checkdata( L, 1 );
267 lua_pushlstring( L, ld->data, ld->size );
268 return 1;
269}
270
281static int dataL_paste( lua_State *L )
282{
283 LuaData_t *dest = luaL_checkdata( L, 1 );
284 LuaData_t *source = luaL_checkdata( L, 2 );
285 long dx = luaL_checklong( L, 3 ) * dest->elem;
286 long sx = luaL_checklong( L, 4 ) * source->elem;
287 long sw = luaL_checklong( L, 5 ) * source->elem;
288 char *ddata = dest->data;
289 const char *sdata = source->data;
290
291 /* Check fits. */
292 if ( dx + sw > (long)dest->size )
293 return NLUA_ERROR(
294 L, _( "size mismatch: out of bound access dest: %d of %d elements" ),
295 dx + sw, dest->size );
296 else if ( sx + sw > (long)source->size )
297 return NLUA_ERROR(
298 L,
299 _( "size mismatch: out of bound access of source: %d of %d elements" ),
300 sx + sw, source->size );
301
302 /* Copy memory over. */
303 memcpy( &ddata[dx], &sdata[sx], sw );
304
305 /* Return destination. */
306 lua_pushvalue( L, 1 );
307 return 1;
308}
309
321static int dataL_addWeighted( lua_State *L )
322{
323 LuaData_t *A = luaL_checkdata( L, 1 );
324 LuaData_t *B = luaL_checkdata( L, 2 );
325 LuaData_t out;
326 double alpha = luaL_checknumber( L, 3 );
327 double beta = luaL_optnumber( L, 4, 1. - alpha );
328 double bias = luaL_optnumber( L, 5, 0. );
329 int i, n;
330 float *o, *a, *b;
331
332 /* Checks. */
333 if ( A->size != B->size )
334 return NLUA_ERROR(
335 L, _( "size mismatch: A has %d elements but B has %d elements" ),
336 A->size, B->size );
337 if ( A->type != LUADATA_NUMBER || B->type != LUADATA_NUMBER )
338 return NLUA_ERROR( L, _( "%s is only implemented for number types" ),
339 __func__ );
340
341 /* Create new data. */
342 out.size = A->size;
343 out.elem = A->elem;
344 out.type = A->type;
345 out.data = malloc( out.size );
346
347 /* Interpolate. */
348 n = out.size / out.elem;
349 a = (float *)A->data;
350 b = (float *)B->data;
351 o = (float *)out.data;
352 for ( i = 0; i < n; i++ )
353 o[i] = a[i] * alpha + b[i] * beta + bias;
354
355 /* Return new data. */
356 lua_pushdata( L, out );
357 return 1;
358}
359
372static int dataL_convolve2d( lua_State *L )
373{
374 LuaData_t *lI = luaL_checkdata( L, 1 );
375 long iw = luaL_checklong( L, 2 );
376 long ih = luaL_checklong( L, 3 );
377 LuaData_t *lK = luaL_checkdata( L, 4 );
378 long kw = luaL_checklong( L, 5 );
379 long kh = luaL_checklong( L, 6 );
380 LuaData_t out;
381 int kw2, kh2, bw, bh, ow, oh;
382 const float *I = (const float *)lI->data;
383 const float *K = (const float *)lK->data;
384 float *B, *O;
385
386 /* Checks. */
387 if ( iw * ih * 4 * lI->elem != lI->size )
388 return NLUA_ERROR(
389 L, _( "size mismatch for data: got %dx%dx4x%d, expected %d" ), iw, ih,
390 lI->elem, lI->size );
391 if ( kw * kh * 4 * lK->elem != lK->size )
392 return NLUA_ERROR(
393 L, _( "size mismatch for data: got %dx%dx4x%d, expected %d" ), kw, kh,
394 lK->elem, lK->size );
395 if ( lI->type != LUADATA_NUMBER || lK->type != LUADATA_NUMBER )
396 return NLUA_ERROR( L, _( "%s is only implemented for number types" ),
397 __func__ );
398
399 /* Set up. */
400 kw2 = ( kw - 1 ) / 2;
401 kh2 = ( kh - 1 ) / 2;
402
403 /* Create new data. */
404 ow = iw + kw2;
405 oh = ih + kw2;
406 out.elem = lI->elem;
407 out.type = lI->type;
408 out.size = ow * oh * 4 * out.elem;
409 out.data = calloc( out.size, 1 );
410 O = (float *)out.data;
411
412#define POS( U, V, W ) ( 4 * ( ( V ) * ( W ) + ( U ) ) )
413 /* Create buffer. */
414 bw = ow + 2 * kw2;
415 bh = oh + 2 * kh2;
416 B = calloc( bw * bh * 4, sizeof( float ) );
417 for ( int v = 0; v < ih; v++ )
418 memcpy( &B[POS( kw2, v + kh2, bw )], &I[POS( 0, v, iw )],
419 4 * sizeof( float ) * iw );
420
421 /* Convolve. */
422 for ( int v = 0; v < oh; v++ ) {
423 for ( int u = 0; u < ow; u++ ) {
424 for ( int kv = 0; kv < kh; kv++ ) {
425 for ( int ku = 0; ku < kw; ku++ ) {
426 int bu = u + ku;
427 int bv = v + kv;
428 for ( int p = 0; p < 4; p++ )
429 O[POS( u, v, ow ) + p] +=
430 B[POS( bu, bv, bw ) + p] * K[POS( ku, kv, kw ) + p];
431 }
432 }
433 }
434 }
435#undef POS
436
437 /* Cleanup. */
438 free( B );
439
440 /* Return new data. */
441 lua_pushdata( L, out );
442 lua_pushinteger( L, ow );
443 lua_pushinteger( L, oh );
444 return 3;
445}
static int dataL_paste(lua_State *L)
Writes the contents of "source" into "dest".
Definition nlua_data.c:281
static int dataL_addWeighted(lua_State *L)
Returns alpha*A + beta*B + bias.
Definition nlua_data.c:321
static int dataL_eq(lua_State *L)
Compares two datas to see if they are the same.
Definition nlua_data.c:147
LuaData_t * luaL_checkdata(lua_State *L, int ind)
Gets data at index or raises error if there is no data at index.
Definition nlua_data.c:80
static int dataL_get(lua_State *L)
Gets the value of an element.
Definition nlua_data.c:205
static int dataL_convolve2d(lua_State *L)
Does a convolution. You'd rather be writing shaders, right?
Definition nlua_data.c:372
static int dataL_gc(lua_State *L)
Frees a data.
Definition nlua_data.c:132
int lua_isdata(lua_State *L, int ind)
Checks to see if ind is a data.
Definition nlua_data.c:110
LuaData_t * lua_pushdata(lua_State *L, LuaData_t data)
Pushes a data on the stack.
Definition nlua_data.c:94
static const luaL_Reg dataL_methods[]
Definition nlua_data.c:32
static int dataL_new(lua_State *L)
Opens a new data.
Definition nlua_data.c:168
LuaData_t * lua_todata(lua_State *L, int ind)
Lua bindings to interact with datas.
Definition nlua_data.c:69
static int dataL_getSize(lua_State *L)
Gets the number of elements.
Definition nlua_data.c:250
static int dataL_set(lua_State *L)
Sets the value of an element.
Definition nlua_data.c:227
static int dataL_getString(lua_State *L)
Returns the data contents as a string.
Definition nlua_data.c:264
int nlua_loadData(nlua_env env)
Loads the data library.
Definition nlua_data.c:51
static const double c[]
Definition rng.c:256
Wrapper to datas.
Definition nlua_data.h:17
LuaDataType_t type
Definition nlua_data.h:21
void * data
Definition nlua_data.h:20
size_t size
Definition nlua_data.h:18
size_t elem
Definition nlua_data.h:19