Current section
Files
Jump to
Current section
Files
c_src/texture.c
//
// Created by Boyd Multerer on 2019-03-17.
// Copyright © 2019 Kry10 Industries. All rights reserved.
//
#include <string.h>
#include <erl_nif.h>
//=============================================================================
// utilities
//=============================================================================
// Erlang NIF stuff from here down.
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_pixels_g(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pixels;
unsigned int size;
unsigned int g;
// get the parameters
if ( !enif_get_uint(env, argv[0], &size) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &g) ) {return enif_make_badarg(env);}
// prepare the binary
enif_alloc_binary( size, &pixels );
// clear the pixels
memset(pixels.data, g, size);
return enif_make_binary( env, &pixels );
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_pixels_ga(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pixels;
unsigned int size;
unsigned int g;
unsigned int a;
// get the parameters
if ( !enif_get_uint(env, argv[0], &size) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &g) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[2], &a) ) {return enif_make_badarg(env);}
// prepare the binary
enif_alloc_binary( size, &pixels );
// clear the pixels
for( unsigned int i = 0; i < size; i += 2) {
pixels.data[i] = g;
pixels.data[i+1] = a;
}
return enif_make_binary( env, &pixels );
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_pixels_rgb(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pixels;
unsigned int size;
unsigned int r;
unsigned int g;
unsigned int b;
// get the parameters
if ( !enif_get_uint(env, argv[0], &size) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &r) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[2], &g) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[3], &b) ) {return enif_make_badarg(env);}
// prepare the binary
enif_alloc_binary( size, &pixels );
// clear the pixels
for( unsigned int i = 0; i < size; i += 3) {
pixels.data[i] = r;
pixels.data[i+1] = g;
pixels.data[i+2] = b;
}
return enif_make_binary( env, &pixels );
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_pixels_rgba(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pixels;
unsigned int size;
unsigned int r;
unsigned int g;
unsigned int b;
unsigned int a;
// get the parameters
if ( !enif_get_uint(env, argv[0], &size) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &r) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[2], &g) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[3], &b) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[4], &a) ) {return enif_make_badarg(env);}
// prepare the binary
enif_alloc_binary( size, &pixels );
// clear the pixels
for( unsigned int i = 0; i < size; i += 4) {
pixels.data[i] = r;
pixels.data[i+1] = g;
pixels.data[i+2] = b;
pixels.data[i+3] = a;
}
return enif_make_binary( env, &pixels );
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_get_g(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pixels;
unsigned int pos;
// get the parameters
if ( !enif_inspect_binary(env, argv[0], &pixels) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &pos) ) {return enif_make_badarg(env);}
if ( pos >= pixels.size ) {return enif_make_badarg(env);}
// return the value of g
return enif_make_int( env, pixels.data[pos] );
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_get_ga(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pixels;
unsigned int pos;
unsigned int g;
unsigned int a;
// get the parameters
if ( !enif_inspect_binary(env, argv[0], &pixels) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &pos) ) {return enif_make_badarg(env);}
if ( pos >= (pixels.size - 1) ) {return enif_make_badarg(env);}
// get the values
pos *= 2;
g = pixels.data[pos];
a = pixels.data[pos + 1];
return enif_make_tuple2( env,
enif_make_int( env, g ),
enif_make_int( env, a )
);
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_get_rgb(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pixels;
unsigned int pos;
unsigned int r;
unsigned int g;
unsigned int b;
// get the parameters
if ( !enif_inspect_binary(env, argv[0], &pixels) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &pos) ) {return enif_make_badarg(env);}
if ( pos >= (pixels.size - 2) ) {return enif_make_badarg(env);}
// get the values
pos *= 3;
r = pixels.data[pos];
g = pixels.data[pos + 1];
b = pixels.data[pos + 2];
return enif_make_tuple3( env,
enif_make_int( env, r ),
enif_make_int( env, g ),
enif_make_int( env, b )
);
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_get_rgba(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pixels;
unsigned int pos;
unsigned int r;
unsigned int g;
unsigned int b;
unsigned int a;
// get the parameters
if ( !enif_inspect_binary(env, argv[0], &pixels) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &pos) ) {return enif_make_badarg(env);}
if ( pos >= (pixels.size - 3) ) {return enif_make_badarg(env);}
// get the values
pos *= 4;
r = pixels.data[pos];
g = pixels.data[pos + 1];
b = pixels.data[pos + 2];
a = pixels.data[pos + 3];
return enif_make_tuple4( env,
enif_make_int( env, r ),
enif_make_int( env, g ),
enif_make_int( env, b ),
enif_make_int( env, a )
);
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_put_g(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pixels;
unsigned int pos;
unsigned int g;
// get the parameters
if ( !enif_inspect_binary(env, argv[0], &pixels) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &pos) ) {return enif_make_badarg(env);}
if ( pos >= pixels.size ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[2], &g) ) {return enif_make_badarg(env);}
// put the value
pixels.data[pos] = g;
return enif_make_atom(env, "ok");;
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_put_ga(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pixels;
unsigned int pos;
unsigned int g;
unsigned int a;
// get the parameters
if ( !enif_inspect_binary(env, argv[0], &pixels) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &pos) ) {return enif_make_badarg(env);}
if ( pos >= (pixels.size - 1) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[2], &g) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[3], &a) ) {return enif_make_badarg(env);}
// put the value
pos *= 2;
pixels.data[pos] = g;
pixels.data[pos + 1] = a;
return enif_make_atom(env, "ok");;
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_put_rgb(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pixels;
unsigned int pos;
unsigned int r;
unsigned int g;
unsigned int b;
// get the parameters
if ( !enif_inspect_binary(env, argv[0], &pixels) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &pos) ) {return enif_make_badarg(env);}
if ( pos >= (pixels.size - 2) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[2], &r) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[3], &g) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[4], &b) ) {return enif_make_badarg(env);}
// put the value
pos *= 3;
pixels.data[pos] = r;
pixels.data[pos + 1] = g;
pixels.data[pos + 2] = b;
return enif_make_atom(env, "ok");;
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_put_rgba(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pixels;
unsigned int pos;
unsigned int r;
unsigned int g;
unsigned int b;
unsigned int a;
// get the parameters
if ( !enif_inspect_binary(env, argv[0], &pixels) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &pos) ) {return enif_make_badarg(env);}
if ( pos >= (pixels.size - 3) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[2], &r) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[3], &g) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[4], &b) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[5], &a) ) {return enif_make_badarg(env);}
// put the value
pos *= 4;
pixels.data[pos] = r;
pixels.data[pos + 1] = g;
pixels.data[pos + 2] = b;
pixels.data[pos + 3] = a;
return enif_make_atom(env, "ok");;
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_clear_g(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pixels;
unsigned int g;
// get the parameters
if ( !enif_inspect_binary(env, argv[0], &pixels) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &g) ) {return enif_make_badarg(env);}
// clear the pixels
memset(pixels.data, g, pixels.size);
return enif_make_binary( env, &pixels );
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_clear_ga(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pixels;
unsigned int size;
unsigned int g;
unsigned int a;
// get the parameters
if ( !enif_inspect_binary(env, argv[0], &pixels) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &g) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[2], &a) ) {return enif_make_badarg(env);}
// clear the pixels
size = pixels.size / 2;
for( unsigned int i = 0; i < size; i += 2) {
pixels.data[i] = g;
pixels.data[i+1] = a;
}
return enif_make_binary( env, &pixels );
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_clear_rgb(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pixels;
unsigned int size;
unsigned int r;
unsigned int g;
unsigned int b;
// get the parameters
if ( !enif_inspect_binary(env, argv[0], &pixels) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &r) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[2], &g) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[3], &b) ) {return enif_make_badarg(env);}
// clear the pixels
size = pixels.size / 3;
for( unsigned int i = 0; i < size; i += 3) {
pixels.data[i] = r;
pixels.data[i+1] = g;
pixels.data[i+2] = b;
}
return enif_make_binary( env, &pixels );
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_clear_rgba(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary pixels;
unsigned int size;
unsigned int r;
unsigned int g;
unsigned int b;
unsigned int a;
// get the parameters
if ( !enif_inspect_binary(env, argv[0], &pixels) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &r) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[2], &g) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[3], &b) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[4], &a) ) {return enif_make_badarg(env);}
// clear the pixels
size = pixels.size / 4;
for( unsigned int i = 0; i < size; i += 4) {
pixels.data[i] = r;
pixels.data[i+1] = g;
pixels.data[i+2] = b;
pixels.data[i+3] = a;
}
return enif_make_binary( env, &pixels );
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_g_to_rgba(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary g_pixels;
ErlNifBinary rgba_pixels;
unsigned int pix_count;
// get the parameters
if ( !enif_inspect_binary(env, argv[0], &g_pixels) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &pix_count) ) {return enif_make_badarg(env);}
// create the destination binary
enif_alloc_binary( pix_count * 4, &rgba_pixels );
// clear the pixels
unsigned int di;
for( unsigned int i = 0; i < pix_count; i ++) {
di = i * 4;
rgba_pixels.data[di] = g_pixels.data[i];
rgba_pixels.data[di+1] = g_pixels.data[i];
rgba_pixels.data[di+2] = g_pixels.data[i];
rgba_pixels.data[di+3] = 0xff;
}
return enif_make_binary( env, &rgba_pixels );
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_ga_to_rgba(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary ga_pixels;
ErlNifBinary rgba_pixels;
unsigned int pix_count;
// get the parameters
if ( !enif_inspect_binary(env, argv[0], &ga_pixels) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &pix_count) ) {return enif_make_badarg(env);}
// create the destination binary
enif_alloc_binary( pix_count * 4, &rgba_pixels );
// clear the pixels
unsigned int di;
unsigned int si;
for( unsigned int i = 0; i < pix_count; i ++) {
si = i * 2;
di = i * 4;
rgba_pixels.data[di] = ga_pixels.data[si];
rgba_pixels.data[di+1] = ga_pixels.data[si];
rgba_pixels.data[di+2] = ga_pixels.data[si];
rgba_pixels.data[di+3] = ga_pixels.data[si + 1];
}
return enif_make_binary( env, &rgba_pixels );
}
//-----------------------------------------------------------------------------
static ERL_NIF_TERM
nif_rgb_to_rgba(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary rgb_pixels;
ErlNifBinary rgba_pixels;
unsigned int pix_count;
// get the parameters
if ( !enif_inspect_binary(env, argv[0], &rgb_pixels) ) {return enif_make_badarg(env);}
if ( !enif_get_uint(env, argv[1], &pix_count) ) {return enif_make_badarg(env);}
// create the destination binary
enif_alloc_binary( pix_count * 4, &rgba_pixels );
// clear the pixels
unsigned int di;
unsigned int si;
for( unsigned int i = 0; i < pix_count; i ++) {
si = i * 3;
di = i * 4;
rgba_pixels.data[di] = rgb_pixels.data[si];
rgba_pixels.data[di + 1] = rgb_pixels.data[si + 1];
rgba_pixels.data[di + 2] = rgb_pixels.data[si + 2];
rgba_pixels.data[di + 3] = 0xff;
}
return enif_make_binary( env, &rgba_pixels );
}
//=============================================================================
// erl housekeeping. This is the list of functions available to the erl side
static ErlNifFunc nif_funcs[] = {
// {erl_function_name, erl_function_arity, c_function}
{"nif_pixels", 2, nif_pixels_g, 0},
{"nif_pixels", 3, nif_pixels_ga, 0},
{"nif_pixels", 4, nif_pixels_rgb, 0},
{"nif_pixels", 5, nif_pixels_rgba, 0},
{"nif_get_g", 2, nif_get_g, 0},
{"nif_get_ga", 2, nif_get_ga, 0},
{"nif_get_rgb", 2, nif_get_rgb, 0},
{"nif_get_rgba", 2, nif_get_rgba, 0},
{"nif_put", 3, nif_put_g, 0},
{"nif_put", 4, nif_put_ga, 0},
{"nif_put", 5, nif_put_rgb, 0},
{"nif_put", 6, nif_put_rgba, 0},
{"nif_clear", 2, nif_clear_g, 0},
{"nif_clear", 3, nif_clear_ga, 0},
{"nif_clear", 4, nif_clear_rgb, 0},
{"nif_clear", 5, nif_clear_rgba, 0},
{"nif_g_to_rgba", 2, nif_g_to_rgba, 0},
{"nif_ga_to_rgba", 2, nif_ga_to_rgba, 0},
{"nif_rgb_to_rgba", 2, nif_rgb_to_rgba, 0}
};
ERL_NIF_INIT(Elixir.Scenic.Utilities.Texture, nif_funcs, NULL, NULL, NULL, NULL)