blob: be04c9499e321cd7233dec52060186f674aacd11 [file] [log] [blame]
/*
* GStreamer
* Copyright (C) 2009 Luc Deschenaux <luc.deschenaux@freesurf.ch>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstglshadervariables.h"
#if !defined(strtok_r) && defined(G_OS_WIN32)
#if defined(_MSC_VER)
#define strtok_r strtok_s
#else
#define strtok_r(s,d,p) strtok(s,d)
#endif
#endif
#define trimleft(s,chars) while(s[0] && strchr(chars,s[0])) ++s;
#define trimright(s,chars) { \
char *end; \
end=s+strlen(s)-1; \
while(end>=s && strchr(chars,end[0])) (end--)[0]=0; \
}
const char *gst_gl_shadervariable_datatype[] = {
"bool",
"int",
"uint",
"float",
"vec2",
"vec3",
"vec4",
"bvec2",
"bvec3",
"bvec4",
"ivec2",
"ivec3",
"ivec4",
"uvec2",
"uvec3",
"uvec4",
"mat2",
"mat3",
"mat4",
"mat2x2",
"mat2x3",
"mat2x4",
"mat3x2",
"mat3x3",
"mat3x4",
"mat4x2",
"mat4x3",
"mat4x4",
0
};
typedef enum
{
_bool,
_int,
_uint,
_float,
_vec2,
_vec3,
_vec4,
_bvec2,
_bvec3,
_bvec4,
_ivec2,
_ivec3,
_ivec4,
_uvec2,
_uvec3,
_uvec4,
_mat2,
_mat3,
_mat4,
_mat2x2,
_mat2x3,
_mat2x4,
_mat3x2,
_mat3x3,
_mat3x4,
_mat4x2,
_mat4x3,
_mat4x4,
_datatypecount
} gst_gl_shadervariable_datatypeindex;
typedef struct gst_gl_shadervariable_desc
{
gst_gl_shadervariable_datatypeindex type;
char *name;
int arraysize;
int count;
void *value;
} gst_gl_shadervariable_desc;
char *parsename (char **varname, int *arraysize, char **saveptr);
char *parsevalue (char *value, char *_saveptr,
struct gst_gl_shadervariable_desc *ret);
char *vec_parsevalue (int n, char *value, char *_saveptr,
struct gst_gl_shadervariable_desc *ret);
char *bvec_parsevalue (int n, char *value, char *_saveptr,
struct gst_gl_shadervariable_desc *ret);
char *ivec_parsevalue (int n, char *value, char *_saveptr,
struct gst_gl_shadervariable_desc *ret);
char *uvec_parsevalue (int n, char *value, char *_saveptr,
struct gst_gl_shadervariable_desc *ret);
char *mat_parsevalue (int n, int m, char *value, char *_saveptr,
struct gst_gl_shadervariable_desc *ret);
/*
Function:
gst_gl_shadervariables_parse
Description:
Parse uniform variables declarations and set their values in
the specified shader.
Arguments:
GstGLShader *shader:
Shader in which variables are to be set.
char *variables:
The text to be parsed.
int (*_setvariable)():
Defaults to gst_gl_shadervariable_set().
You can specify here a user function for managing the
parsed variable description.
return values:
0: No error.
-1: Error.
*/
int
gst_gl_shadervariables_parse (GstGLShader * shader, char *variables,
int (*_setvariable) (GstGLShader * shader,
struct gst_gl_shadervariable_desc * v))
{
char *p = 0;
char *p0;
char *e;
char e1 = 0;
char *t = 0;
char *varname;
char *vartype;
char *varvalue;
int arraysize = 0;
char *saveptr = variables;
int line = 1;
char *lim;
int i;
int len;
struct gst_gl_shadervariable_desc ret;
if (!_setvariable) {
_setvariable = gst_gl_shadervariable_set;
}
if (!variables)
return 0;
p0 = variables;
trimright (p0, " \t\r\n");
lim = variables + strlen (variables);
e = strchr (p0, ';');
while (p0 < lim) {
if (!e) {
if (p0[0])
goto parse_error;
break;
}
e1 = e[1];
e[1] = 0;
p = g_strdup (p0);
e[1] = e1;
trimright (p, " \t");
trimleft (p, " \t\r\n");
t = strtok_r (p, " \t", &saveptr);
if (!t)
goto parse_error;
trimleft (t, " \t");
trimright (t, " \t\r\n");
if (t[0]) {
if (!strcmp (t, "const")) {
t = strtok_r (0, " \t", &saveptr);
if (!t)
goto parse_error;
trimleft (t, " \t");
if (!t[0])
goto parse_error;
}
// parse data type
for (i = 0; i < _datatypecount; ++i) {
if (!strcmp (t, gst_gl_shadervariable_datatype[i])) {
ret.type = (gst_gl_shadervariable_datatypeindex) i;
break;
}
}
if (i == _datatypecount)
goto parse_error;
vartype = g_strdup (t);
GST_INFO ("vartype : '%s'\n", vartype);
trimleft (saveptr, " \t");
t = saveptr;
if (*saveptr == '=')
goto parse_error;
// parse variable name and array size
t = parsename (&varname, &arraysize, &saveptr);
if (t)
goto parse_error;
trimright (varname, " \t");
GST_INFO ("varname : '%s'\n", varname);
GST_INFO ("arraysize : %d\n", arraysize);
// check type cast after assignement operator
t = strtok_r (0, "(", &saveptr);
if (!t)
goto parse_error;
trimleft (t, " \t");
trimright (t, " \t");
if (arraysize) {
gchar *s = g_strdup_printf ("%s[%d]", vartype, arraysize);
if (strcmp (t, s)) {
g_free (s);
goto parse_error;
}
g_free (s);
} else {
if (strcmp (t, vartype))
goto parse_error;
}
// extract variable value
t = strtok_r (0, ";", &saveptr);
if (!t)
goto parse_error;
trimleft (t, " \t");
trimright (t, " \t");
if (!t[0])
goto parse_error;
if (*(saveptr - 2) != ')')
goto parse_error;
*(saveptr - 2) = 0;
if (!t[0])
goto parse_error;
varvalue = g_strdup (t);
GST_INFO ("value: %s\n\n", varvalue);
t = saveptr;
if (t[0])
goto parse_error;
// parse variable value
len = strlen (varvalue);
ret.name = varname;
ret.arraysize = arraysize;
t = parsevalue (varvalue, saveptr, &ret);
if (t) {
t -= len;
goto parse_error;
}
// set variable value
_setvariable (shader, &ret);
fflush (0);
}
// Tell me why we cannot free(p) whithout segfault.
//g_free(p);
p0 = e + 1;
++line;
e = strchr (p0, ';');
}
return 0;
parse_error:
if (!t) {
t = saveptr;
}
if (!e) {
t = p = p0;
} else {
e[1] = 0;
trimleft (p0, " \t\r\n");
GST_ERROR ("\n%s", p0);
e[1] = e1;
}
GST_ERROR ("parse error on line %d, position %ld (%s)", line, (glong) (t - p),
t);
return -1;
}
/*
Function:
parsename
Description:
Parse text between the data type and the assignement operator
(ie: variable name and array size).
Arguments:
char **varname:
Text to parse.
int *arraysize:
Pointer to array size. Set to 0 if no array.
char **saveptr:
Address of char *saveptr for strtok_r()
return values:
0: No error.
!0: Pointer to parse error.
*/
char *
parsename (char **varname, int *arraysize, char **saveptr)
{
char *t;
char *i;
gint j;
*arraysize = 0;
t = strtok_r (0, "=", saveptr);
if (!t)
return *saveptr;
trimleft (t, " \t");
trimright (t, " \t");
i = strchr (t, '[');
if (!i) { // not an array
if (!t[0])
return t;
for (j = 0; j < (gint) strlen (t); ++j) {
if (!strchr (VALID_VARNAME_CHARS, t[j]))
return t + j;
}
*varname = g_strdup (t);
} else { // is an array
char *i2;
char *c;
i2 = strchr (i + 1, ']');
if (!i2)
return i + 1;
*i = 0;
if (!t[0])
return t;
for (j = 0; j < (gint) strlen (t); ++j) {
if (!strchr (VALID_VARNAME_CHARS, t[j]))
return t;
}
*varname = g_strdup (t);
*i = '[';
for (c = i + 1; c < i2; ++c)
if (*c < '0' || *c > '9')
return c;
*i2 = 0;
*arraysize = atoi (i + 1);
*i2 = ']';
if (!*arraysize)
return i + 1;
}
return 0;
}
/*
Function:
gst_gl_shadervariable_set
Description:
Set variable value in the specified shader
Arguments:
GstGlShader *shader:
The shader where to set the variable.
struct gst_gl_shadervariable_desc *ret:
The variable description.
return values:
0: No error.
!0: Variable type unknown/incorrect.
*/
int
gst_gl_shadervariable_set (GstGLShader * shader,
struct gst_gl_shadervariable_desc *ret)
{
switch (ret->type) {
case _bool:
if (ret->arraysize) {
gst_gl_shader_set_uniform_1iv (shader, ret->name, ret->count,
(int *) ret->value);
} else {
gst_gl_shader_set_uniform_1i (shader, ret->name,
((int *) ret->value)[0]);
}
break;
case _int:
if (ret->arraysize) {
gst_gl_shader_set_uniform_1iv (shader, ret->name, ret->count,
(int *) ret->value);
} else {
gst_gl_shader_set_uniform_1i (shader, ret->name,
((int *) ret->value)[0]);
}
break;
case _uint:
if (ret->arraysize) {
gst_gl_shader_set_uniform_1iv (shader, ret->name, ret->count,
(int *) ret->value);
} else {
gst_gl_shader_set_uniform_1i (shader, ret->name,
((unsigned int *) ret->value)[0]);
}
break;
case _float:
if (ret->arraysize) {
gst_gl_shader_set_uniform_1fv (shader, ret->name, ret->count,
(float *) ret->value);
} else {
gst_gl_shader_set_uniform_1f (shader, ret->name,
((float *) ret->value)[0]);
}
break;
case _vec2:
if (ret->arraysize) {
gst_gl_shader_set_uniform_2fv (shader, ret->name, ret->count,
(float *) ret->value);
} else {
gst_gl_shader_set_uniform_2f (shader, ret->name,
((float *) ret->value)[0], ((float *) ret->value)[1]);
}
break;
case _bvec2:
case _ivec2:
case _uvec2:
if (ret->arraysize) {
gst_gl_shader_set_uniform_2iv (shader, ret->name, ret->count,
(int *) ret->value);
} else {
gst_gl_shader_set_uniform_2i (shader, ret->name,
((int *) ret->value)[0], ((int *) ret->value)[1]);
}
break;
case _vec3:
if (ret->arraysize) {
gst_gl_shader_set_uniform_3fv (shader, ret->name, ret->count,
(float *) ret->value);
} else {
gst_gl_shader_set_uniform_3f (shader, ret->name,
((float *) ret->value)[0], ((float *) ret->value)[1],
((float *) ret->value)[2]);
}
break;
case _bvec3:
case _ivec3:
case _uvec3:
if (ret->arraysize) {
gst_gl_shader_set_uniform_3iv (shader, ret->name, ret->count,
(int *) ret->value);
} else {
gst_gl_shader_set_uniform_3i (shader, ret->name,
((int *) ret->value)[0], ((int *) ret->value)[1],
((int *) ret->value)[2]);
}
break;
case _vec4:
if (ret->arraysize) {
gst_gl_shader_set_uniform_4fv (shader, ret->name, ret->count,
(float *) ret->value);
} else {
gst_gl_shader_set_uniform_4f (shader, ret->name,
((float *) ret->value)[0], ((float *) ret->value)[1],
((float *) ret->value)[2], ((float *) ret->value)[3]);
}
break;
case _bvec4:
case _ivec4:
case _uvec4:
if (ret->arraysize) {
gst_gl_shader_set_uniform_4iv (shader, ret->name, ret->count,
(int *) ret->value);
} else {
gst_gl_shader_set_uniform_4i (shader, ret->name,
((int *) ret->value)[0], ((int *) ret->value)[1],
((int *) ret->value)[2], ((int *) ret->value)[3]);
}
break;
case _mat2:
case _mat2x2:
gst_gl_shader_set_uniform_matrix_2fv (shader, ret->name, ret->count, 0,
(float *) ret->value);
break;
case _mat3:
case _mat3x3:
gst_gl_shader_set_uniform_matrix_3fv (shader, ret->name, ret->count, 0,
(float *) ret->value);
break;
case _mat4:
case _mat4x4:
gst_gl_shader_set_uniform_matrix_4fv (shader, ret->name, ret->count, 0,
(float *) ret->value);
break;
#if GST_GL_HAVE_OPENGL
case _mat2x3:
gst_gl_shader_set_uniform_matrix_2x3fv (shader, ret->name, ret->count, 0,
(float *) ret->value);
break;
case _mat3x2:
gst_gl_shader_set_uniform_matrix_3x2fv (shader, ret->name, ret->count, 0,
(float *) ret->value);
break;
case _mat2x4:
gst_gl_shader_set_uniform_matrix_2x4fv (shader, ret->name, ret->count, 0,
(float *) ret->value);
break;
case _mat4x2:
gst_gl_shader_set_uniform_matrix_4x2fv (shader, ret->name, ret->count, 0,
(float *) ret->value);
break;
case _mat3x4:
gst_gl_shader_set_uniform_matrix_3x4fv (shader, ret->name, ret->count, 0,
(float *) ret->value);
break;
case _mat4x3:
gst_gl_shader_set_uniform_matrix_4x3fv (shader, ret->name, ret->count, 0,
(float *) ret->value);
break;
#endif
default:
return -1;
}
return 0;
}
/*
Function:
parsevalue
Description:
Parse text coming after the assignement operator for scalar
variables or call the appropriate subroutine to parse vector
variables.
Arguments:
char *value:
Text to be parsed.
char *_saveptr:
Index of end of value.
struct gst_gl_shadervariable_desc *ret:
The variable description to be completed
At input time it contains the data type index (type),
variable name (name) and array size (arraysize).
return values:
0: No error.
!0: Pointer to parse error.
*/
char *
parsevalue (char *value, char *_saveptr, struct gst_gl_shadervariable_desc *ret)
{
int i, j;
char *t;
char *saveptr = value;
switch (ret->type) {
case _bool:
ret->count = (ret->arraysize) ? ret->arraysize : 1;
if (ret->count == 1) { // no array
if (strcmp (value, "true") && strcmp (value, "false"))
return _saveptr;
ret->value = (void *) g_malloc (sizeof (int));
((int *) ret->value)[0] = strcmp (value, "false");
} else { // array
ret->value = g_malloc (sizeof (int *) * ret->count);
t = strtok_r (value, ",", &saveptr);
for (i = 0; i < ret->count; ++i) {
if (!t)
return _saveptr + (saveptr - value);
trimleft (t, " \t");
trimright (t, " \t");
if (strcmp (t, "true") && strcmp (t, "false"))
return _saveptr + (saveptr - t);
((int *) ret->value)[i] = strcmp (t, "false");
t = strtok_r (0, ",", &saveptr);
}
}
break;
case _int:
ret->count = (ret->arraysize) ? ret->arraysize : 1;
if (ret->count == 1) {
for (j = 0; j < (gint) strlen (value); ++j) {
if (!strchr ("-0123456789", value[j]))
return _saveptr + j;
}
ret->value = (void *) g_malloc (sizeof (int));
*((int *) ret->value) = atoi (value);
} else {
ret->value = g_malloc (sizeof (int) * ret->count);
t = strtok_r (value, ",", &saveptr);
for (i = 0; i < ret->count; ++i) {
if (!t)
return _saveptr + (saveptr - value);
trimleft (t, " \t");
trimright (t, " \t");
if (!t[0])
return _saveptr + (saveptr - t);
for (j = 0; j < (gint) strlen (value); ++j) {
if (!strchr ("-0123456789", value[j]))
return _saveptr + (saveptr - t) + j;
}
((int *) ret->value)[i] = atoi (t);
t = strtok_r (0, ",", &saveptr);
}
}
break;
case _uint:
ret->count = (ret->arraysize) ? ret->arraysize : 1;
if (ret->count == 1) {
for (j = 0; j < (gint) strlen (value); ++j) {
if (!strchr ("0123456789", value[j]))
return _saveptr + j;
}
ret->value = (void *) g_malloc (sizeof (unsigned int));
*((unsigned int *) ret->value) = atoi (value);
} else {
ret->value = g_malloc (sizeof (unsigned int) * ret->count);
t = strtok_r (value, ",", &saveptr);
for (i = 0; i < ret->count; ++i) {
if (!t)
return _saveptr + (saveptr - value);
trimleft (t, " \t");
trimright (t, " \t");
if (!t[0])
return _saveptr + (saveptr - t);
for (j = 0; j < (gint) strlen (value); ++j) {
if (!strchr ("0123456789", value[j]))
return _saveptr + (saveptr - t) + j;
}
((unsigned int *) ret->value)[i] = atoi (t);
t = strtok_r (0, ",", &saveptr);
}
}
break;
case _float:
ret->count = (ret->arraysize) ? ret->arraysize : 1;
if (ret->count == 1) {
for (j = 0; j < (gint) strlen (value); ++j) {
if (!strchr ("0123456789.-", value[j]))
return _saveptr + j;
}
ret->value = (void *) g_malloc (sizeof (float));
*((float *) ret->value) = (float) g_ascii_strtod (value, NULL);
} else {
ret->value = g_malloc (sizeof (float) * ret->count);
t = strtok_r (value, ",", &saveptr);
for (i = 0; i < ret->count; ++i) {
if (!t)
return _saveptr + (saveptr - value);
trimleft (t, " \t");
trimright (t, " \t");
if (!t[0])
return _saveptr + (saveptr - t);
for (j = 0; j < (gint) strlen (value); ++j) {
if (!strchr ("0123456789.-", value[j]))
return _saveptr + (saveptr - t) + j;
}
((float *) ret->value)[i] = (float) g_ascii_strtod (t, NULL);
t = strtok_r (0, ",", &saveptr);
}
}
break;
case _vec2:
return vec_parsevalue (2, value, _saveptr, ret);
break;
case _bvec2:
return bvec_parsevalue (2, value, _saveptr, ret);
break;
case _ivec2:
return ivec_parsevalue (2, value, _saveptr, ret);
break;
case _uvec2:
return uvec_parsevalue (2, value, _saveptr, ret);
break;
case _vec3:
return vec_parsevalue (3, value, _saveptr, ret);
break;
case _bvec3:
return bvec_parsevalue (3, value, _saveptr, ret);
break;
case _ivec3:
return uvec_parsevalue (3, value, _saveptr, ret);
break;
case _uvec3:
return uvec_parsevalue (3, value, _saveptr, ret);
break;
case _vec4:
return vec_parsevalue (4, value, _saveptr, ret);
break;
case _bvec4:
return bvec_parsevalue (4, value, _saveptr, ret);
break;
case _ivec4:
return ivec_parsevalue (4, value, _saveptr, ret);
break;
case _uvec4:
return uvec_parsevalue (4, value, _saveptr, ret);
break;
case _mat2:
case _mat2x2:
return mat_parsevalue (2, 2, value, _saveptr, ret);
break;
case _mat2x3:
return mat_parsevalue (2, 3, value, _saveptr, ret);
break;
case _mat3x2:
return mat_parsevalue (3, 2, value, _saveptr, ret);
break;
case _mat2x4:
return mat_parsevalue (2, 4, value, _saveptr, ret);
break;
case _mat4x2:
return mat_parsevalue (4, 2, value, _saveptr, ret);
break;
case _mat3:
case _mat3x3:
return mat_parsevalue (3, 3, value, _saveptr, ret);
break;
case _mat3x4:
return mat_parsevalue (3, 4, value, _saveptr, ret);
break;
case _mat4x3:
return mat_parsevalue (4, 3, value, _saveptr, ret);
break;
case _mat4:
case _mat4x4:
return mat_parsevalue (4, 4, value, _saveptr, ret);
break;
default:
break;
}
return 0;
}
/*
Function:
vec_parsevalue
Description:
Parse text coming after the assignement operator for vec
type variables.
Arguments:
int n;
Vector dimension.
char *value:
Text to be parsed.
char *_saveptr:
Index of end of value.
struct gst_gl_shadervariable_desc *ret:
The variable description to be completed
At input time it contains the data type index (type),
variable name (name) and array size (arraysize).
return values:
0: No error.
!0: Pointer to parse error.
*/
char *
vec_parsevalue (int n, char *value, char *_saveptr,
struct gst_gl_shadervariable_desc *ret)
{
int i;
int j;
int k;
char *saveptr = value;
char *saveptr2;
char *t;
char *u;
ret->count = (ret->arraysize) ? ret->arraysize * n : n;
ret->value = g_malloc (sizeof (float) * ret->count);
if (!ret->arraysize) {
t = strtok_r (value, ",", &saveptr);
for (i = 0; i < ret->count; ++i) {
if (!t)
return _saveptr + (saveptr - value);
trimleft (t, " \t");
trimright (t, " \t");
if (!t[0])
return _saveptr + (saveptr - t);
for (j = 0; j < (gint) strlen (value); ++j) {
if (!strchr ("0123456789.-", value[j]))
return _saveptr + (saveptr - t) + j;
}
((float *) ret->value)[i] = (float) g_ascii_strtod (t, NULL);
t = strtok_r (0, ",", &saveptr);
}
} else {
saveptr2 = value;
u = strtok_r (value, ")", &saveptr2);
for (k = 0; k < ret->arraysize; ++k) {
if (!u)
return _saveptr + (saveptr2 - value);
trimleft (u, " \t");
trimright (u, " \t");
if (k) {
if (u[0] != ',')
return _saveptr + (u - value);
++u;
trimleft (u, " \t");
}
if (strncmp (u, gst_gl_shadervariable_datatype[ret->type],
strlen (gst_gl_shadervariable_datatype[ret->type])))
return _saveptr + (u - value);
u += strlen (gst_gl_shadervariable_datatype[ret->type]);
trimleft (u, " \t");
if (u[0] != '(')
return _saveptr + (u - value);
++u;
t = strtok_r (u, ",", &saveptr);
if (!t)
return _saveptr + (u - value);
for (i = 0; i < n; ++i) {
trimleft (t, " \t");
trimright (t, " \t");
if (!t[0])
return _saveptr + (t - value);
for (j = 0; j < (gint) strlen (t); ++j) {
if (!strchr ("0123456789.-", t[j]))
return _saveptr + (t - value) + j;
}
((float *) ret->value)[k * n + i] = (float) g_ascii_strtod (t, NULL);
t = strtok_r (0, ",", &saveptr);
if (i < (n - 1) && !t)
return _saveptr + (saveptr - value);
}
u = strtok_r (0, ")", &saveptr2);
}
}
return 0;
}
/*
Function:
bvec_parsevalue
Description:
Parse text coming after the assignement operator for bvec
type variables.
Arguments:
int n;
Vector dimension.
char *value:
Text to be parsed.
char *_saveptr:
Index of end of value.
struct gst_gl_shadervariable_desc *ret:
The variable description to be completed
At input time it contains the data type index (type),
variable name (name) and array size (arraysize).
return values:
0: No error.
!0: Pointer to parse error.
*/
char *
bvec_parsevalue (int n, char *value, char *_saveptr,
struct gst_gl_shadervariable_desc *ret)
{
int i;
int k;
char *saveptr = value;
char *saveptr2;
char *t;
char *u;
ret->count = (ret->arraysize) ? ret->arraysize * n : n;
ret->value = g_malloc (sizeof (char **) * ret->count);
if (!ret->arraysize) {
t = strtok_r (value, ",", &saveptr);
for (i = 0; i < ret->count; ++i) {
if (!t)
return _saveptr + (saveptr - value);
trimleft (t, " \t");
trimright (t, " \t");
if (!t[0])
return _saveptr + (saveptr - t);
if (strcmp ("true", value) || strcmp ("false", value))
return _saveptr + (saveptr - t);
((int *) ret->value)[i] = strcmp (t, "false");
t = strtok_r (0, ",", &saveptr);
}
} else {
saveptr2 = value;
u = strtok_r (value, ")", &saveptr2);
for (k = 0; k < ret->arraysize; ++k) {
if (!u)
return _saveptr + (saveptr2 - value);
trimleft (u, " \t");
trimright (u, " \t");
if (k) {
if (u[0] != ',')
return _saveptr + (u - value);
++u;
trimleft (u, " \t");
}
if (strncmp (u, gst_gl_shadervariable_datatype[ret->type],
strlen (gst_gl_shadervariable_datatype[ret->type])))
return _saveptr + (u - value);
u += strlen (gst_gl_shadervariable_datatype[ret->type]);
trimleft (u, " \t");
if (u[0] != '(')
return _saveptr + (u - value);
++u;
t = strtok_r (u, ",", &saveptr);
if (!t)
return _saveptr + (u - value);
for (i = 0; i < n; ++i) {
trimleft (t, " \t");
trimright (t, " \t");
if (!t[0])
return _saveptr + (t - value);
if (strcmp ("true", t) || strcmp ("false", t))
return _saveptr + (saveptr - t);
((int *) ret->value)[k * n + i] = strcmp (t, "false");
t = strtok_r (0, ",", &saveptr);
if (i < (n - 1) && !t)
return _saveptr + (saveptr - value);
}
u = strtok_r (0, ")", &saveptr2);
}
}
return 0;
}
/*
Function:
ivec_parsevalue
Description:
Parse text coming after the assignement operator for ivec
type variables.
Arguments:
int n;
Vector dimension.
char *value:
Text to be parsed.
char *_saveptr:
Index of end of value.
struct gst_gl_shadervariable_desc *ret:
The variable description to be completed
At input time it contains the data type index (type),
variable name (name) and array size (arraysize).
return values:
0: No error.
!0: Pointer to parse error.
*/
char *
ivec_parsevalue (int n, char *value, char *_saveptr,
struct gst_gl_shadervariable_desc *ret)
{
int i;
int j;
int k;
char *saveptr = value;
char *saveptr2;
char *t;
char *u;
ret->count = (ret->arraysize) ? ret->arraysize * n : n;
ret->value = g_malloc (sizeof (int) * ret->count);
if (!ret->arraysize) {
t = strtok_r (value, ",", &saveptr);
for (i = 0; i < ret->count; ++i) {
if (!t)
return _saveptr + (saveptr - value);
trimleft (t, " \t");
trimright (t, " \t");
if (!t[0])
return _saveptr + (saveptr - t);
for (j = 0; j < (gint) strlen (value); ++j) {
if (!strchr ("0123456789-", value[j]))
return _saveptr + (saveptr - t) + j;
}
((int *) ret->value)[i] = atoi (t);
t = strtok_r (0, ",", &saveptr);
}
} else {
saveptr2 = value;
u = strtok_r (value, ")", &saveptr2);
for (k = 0; k < ret->arraysize; ++k) {
if (!u)
return _saveptr + (saveptr2 - value);
trimleft (u, " \t");
trimright (u, " \t");
if (k) {
if (u[0] != ',')
return _saveptr + (u - value);
++u;
trimleft (u, " \t");
}
if (strncmp (u, gst_gl_shadervariable_datatype[ret->type],
strlen (gst_gl_shadervariable_datatype[ret->type])))
return _saveptr + (u - value);
u += strlen (gst_gl_shadervariable_datatype[ret->type]);
trimleft (u, " \t");
if (u[0] != '(')
return _saveptr + (u - value);
++u;
t = strtok_r (u, ",", &saveptr);
if (!t)
return _saveptr + (u - value);
for (i = 0; i < n; ++i) {
trimleft (t, " \t");
trimright (t, " \t");
if (!t[0])
return _saveptr + (t - value);
for (j = 0; j < (gint) strlen (t); ++j) {
if (!strchr ("0123456789-", t[j]))
return _saveptr + (t - value) + j;
}
((int *) ret->value)[k * n + i] = atoi (t);
t = strtok_r (0, ",", &saveptr);
if (i < (n - 1) && !t)
return _saveptr + (saveptr - value);
}
u = strtok_r (0, ")", &saveptr2);
}
}
return 0;
}
/*
Function:
uvec_parsevalue
Description:
Parse text coming after the assignement operator for uvec
type variables.
Arguments:
int n;
Vector dimension.
char *value:
Text to be parsed.
char *_saveptr:
Index of end of value.
struct gst_gl_shadervariable_desc *ret:
The variable description to be completed
At input time it contains the data type index (type),
variable name (name) and array size (arraysize).
return values:
0: No error.
!0: Pointer to parse error.
*/
char *
uvec_parsevalue (int n, char *value, char *_saveptr,
struct gst_gl_shadervariable_desc *ret)
{
int i;
int j;
int k;
char *saveptr = value;
char *saveptr2;
char *t;
char *u;
ret->count = (ret->arraysize) ? ret->arraysize * n : n;
ret->value = g_malloc (sizeof (unsigned int) * ret->count);
if (!ret->arraysize) {
t = strtok_r (value, ",", &saveptr);
for (i = 0; i < ret->count; ++i) {
if (!t)
return _saveptr + (saveptr - value);
trimleft (t, " \t");
trimright (t, " \t");
if (!t[0])
return _saveptr + (saveptr - t);
for (j = 0; j < (gint) strlen (value); ++j) {
if (!strchr ("0123456789", value[j]))
return _saveptr + (saveptr - t) + j;
}
((unsigned int *) ret->value)[i] = atoi (t);
t = strtok_r (0, ",", &saveptr);
}
} else {
saveptr2 = value;
u = strtok_r (value, ")", &saveptr2);
for (k = 0; k < ret->arraysize; ++k) {
if (!u)
return _saveptr + (saveptr2 - value);
trimleft (u, " \t");
trimright (u, " \t");
if (k) {
if (u[0] != ',')
return _saveptr + (u - value);
++u;
trimleft (u, " \t");
}
if (strncmp (u, gst_gl_shadervariable_datatype[ret->type],
strlen (gst_gl_shadervariable_datatype[ret->type])))
return _saveptr + (u - value);
u += strlen (gst_gl_shadervariable_datatype[ret->type]);
trimleft (u, " \t");
if (u[0] != '(')
return _saveptr + (u - value);
++u;
t = strtok_r (u, ",", &saveptr);
if (!t)
return _saveptr + (u - value);
for (i = 0; i < n; ++i) {
trimleft (t, " \t");
trimright (t, " \t");
if (!t[0])
return _saveptr + (t - value);
for (j = 0; j < (gint) strlen (t); ++j) {
if (!strchr ("0123456789", t[j]))
return _saveptr + (t - value) + j;
}
((unsigned int *) ret->value)[k * n + i] = atoi (t);
t = strtok_r (0, ",", &saveptr);
if (i < (n - 1) && !t)
return _saveptr + (saveptr - value);
}
u = strtok_r (0, ")", &saveptr2);
}
}
return 0;
}
/*
Function:
mat_parsevalue
Description:
Parse text coming after the assignement operator for matrix
type variables.
Arguments:
int n,m;
Matrix dimensions.
char *value:
Text to be parsed.
char *_saveptr:
Index of end of value.
struct gst_gl_shadervariable_desc *ret:
The variable description to be completed
At input time it contains the data type index (type),
variable name (name) and array size (arraysize).
return values:
0: No error.
!0: Pointer to parse error.
*/
char *
mat_parsevalue (int n, int m, char *value, char *_saveptr,
struct gst_gl_shadervariable_desc *ret)
{
int i;
int j;
int k;
char *saveptr = value;
char *saveptr2;
char *t;
char *u;
ret->count = (ret->arraysize) ? ret->arraysize * n * m : n * m;
ret->value = g_malloc (sizeof (float) * ret->count);
if (!ret->arraysize) {
t = strtok_r (value, ",", &saveptr);
for (i = 0; i < ret->count; ++i) {
if (!t)
return _saveptr + (saveptr - value);
trimleft (t, " \t");
trimright (t, " \t");
if (!t[0])
return _saveptr + (saveptr - t);
for (j = 0; j < (gint) strlen (value); ++j) {
if (!strchr ("0123456789.-", value[j]))
return _saveptr + (saveptr - t) + j;
}
((float *) ret->value)[i] = (float) g_ascii_strtod (t, NULL);
t = strtok_r (0, ",", &saveptr);
}
} else {
saveptr2 = value;
u = strtok_r (value, ")", &saveptr2);
for (k = 0; k < ret->arraysize; ++k) {
if (!u)
return _saveptr + (saveptr2 - value);
trimleft (u, " \t");
trimright (u, " \t");
if (k) {
if (u[0] != ',')
return _saveptr + (u - value);
++u;
trimleft (u, " \t");
}
if (strncmp (u, gst_gl_shadervariable_datatype[ret->type],
strlen (gst_gl_shadervariable_datatype[ret->type])))
return _saveptr + (u - value);
u += strlen (gst_gl_shadervariable_datatype[ret->type]);
trimleft (u, " \t");
if (u[0] != '(')
return _saveptr + (u - value);
++u;
t = strtok_r (u, ",", &saveptr);
if (!t)
return _saveptr + (u - value);
for (i = 0; i < n * m; ++i) {
trimleft (t, " \t");
trimright (t, " \t");
if (!t[0])
return _saveptr + (t - value);
for (j = 0; j < (gint) strlen (t); ++j) {
if (!strchr ("0123456789.-", t[j]))
return _saveptr + (t - value) + j;
}
((float *) ret->value)[k * n * m + i] =
(float) g_ascii_strtod (t, NULL);
t = strtok_r (0, ",", &saveptr);
if (i < (n * m - 1) && !t)
return _saveptr + (saveptr - value);
}
u = strtok_r (0, ")", &saveptr2);
}
}
return 0;
}