mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-27 10:40:34 +00:00
1a613c5d4e
Floating point numbers are written differently in different locales, e.g. in many countries 1/2 = 0,5 instead of 0.5, and strtod will not be able to parse "0.5" correctly in such a locale.
1488 lines
33 KiB
C
1488 lines
33 KiB
C
/*
|
|
* 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;
|
|
}
|