Skip to content

Instantly share code, notes, and snippets.

@stakira
Last active September 26, 2021 12:08
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stakira/26c4323e3d78ab01aeb7 to your computer and use it in GitHub Desktop.
Save stakira/26c4323e3d78ab01aeb7 to your computer and use it in GitHub Desktop.
LuaJIT FFI 2D matrix with continuously allocated data array.
#include <cinttypes>
extern "C" {
__declspec(dllexport) void array_to_mat2d_byte(unsigned char* data, unsigned char** mat, size_t w, size_t h) {
for (size_t i = 0; i < w; ++i) {
mat[i] = data + h * i;
}
}
__declspec(dllexport) void array_to_mat2d_int32(int32_t* data, int32_t** mat, size_t w, size_t h) {
for (size_t i = 0; i < w; ++i) {
mat[i] = data + h * i;
}
}
__declspec(dllexport) void array_to_mat2d_int64(int64_t* data, int64_t** mat, size_t w, size_t h) {
for (size_t i = 0; i < w; ++i) {
mat[i] = data + h * i;
}
}
__declspec(dllexport) void array_to_mat2d_float(float* data, float** mat, size_t w, size_t h) {
for (size_t i = 0; i < w; ++i) {
mat[i] = data + h * i;
}
}
}
ffi = require 'ffi'
local lib = ffi.load('mat2d')
ffi.cdef[[
void array_to_mat2d_byte(unsigned char* data, unsigned char** mat, size_t w, size_t h);
void array_to_mat2d_int32(int32_t* data, int32_t** mat, size_t w, size_t h);
void array_to_mat2d_int64(int64_t* data, int64_t** mat, size_t w, size_t h);
void array_to_mat2d_float(float* data, float** mat, size_t w, size_t h);
]]
local mat2d = {}
--[[
the idea is `mat` is the short cut to access actual data in `data`.
both reference must be kept to avoid gc.
--]]
function mat2d.byte(w, h)
local data = ffi.new('unsigned char [?]', w * h)
local mat = ffi.new('unsigned char *[?]', w)
lib.array_to_mat2d_byte(data, mat, w, h)
return data, mat
end
function mat2d.int32(w, h)
local data = ffi.new('int32_t [?]', w * h)
local mat = ffi.new('int32_t *[?]', w)
lib.array_to_mat2d_int32(data, mat, w, h)
return data, mat
end
function mat2d.int64(w, h)
local data = ffi.new('int64_t [?]', w * h)
local mat = ffi.new('int64_t *[?]', w)
lib.array_to_mat2d_int64(data, mat, w, h)
return data, mat
end
function mat2d.float(w, h)
local data = ffi.new('float [?]', w * h)
local mat = ffi.new('float *[?]', w)
lib.array_to_mat2d_float(data, mat, w, h)
return data, mat
end
return mat2d
-- pure Lua version. A little slower than C version.
function mat2d.byte(w, h)
local data = ffi.new('unsigned char [?]', w * h)
local data_ptr = ffi.cast('unsigned char*', data)
local mat = ffi.new('unsigned char *[?]', w)
for i = 0, w - 1 do
mat[i] = data_ptr + i * h
end
return data, mat
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment