Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2022-05-10 00:52:44 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-05-10 00:52:44 +0300
commitb6b94f878ff0b5a89cb8ee1493e4cafd004f8c27 (patch)
tree3c696dc4d3fd1cd584236ed90ad5551539d6c388 /source
parentbda9a1b10387fba141a2ceecc34fb91d37e03862 (diff)
parent7301547ca7eea475b7f41b70d36b079d04708718 (diff)
Merge branch 'blender-v3.2-release'
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenlib/BLI_string.h8
-rw-r--r--source/blender/blenlib/intern/string.c18
-rw-r--r--source/blender/draw/engines/eevee/shaders/closure_eval_surface_lib.glsl7
-rw-r--r--source/blender/draw/engines/eevee/shaders/closure_eval_volume_lib.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/surface_lib.glsl8
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl2
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl1
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl7
-rw-r--r--source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh1
-rw-r--r--source/blender/gpu/intern/gpu_codegen.cc49
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.c4
-rw-r--r--source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl4
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_add_shader.glsl2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl4
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_mix_shader.glsl2
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp31
19 files changed, 91 insertions, 69 deletions
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index 45abac33795..0344622e81d 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -343,8 +343,16 @@ int BLI_strcmp_ignore_pad(const char *str1, const char *str2, char pad) ATTR_WAR
*/
size_t BLI_strnlen(const char *str, size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+/**
+ * String case conversion, not affected by locale.
+ */
+
void BLI_str_tolower_ascii(char *str, size_t len) ATTR_NONNULL();
void BLI_str_toupper_ascii(char *str, size_t len) ATTR_NONNULL();
+
+char BLI_tolower_ascii(const char c);
+char BLI_toupper_ascii(const char c);
+
/**
* Strip white-space from end of the string.
*/
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index 74559751d91..8387eb5f4f9 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -914,14 +914,22 @@ size_t BLI_strnlen(const char *s, const size_t maxlen)
/** \name String Case Conversion
* \{ */
+char BLI_tolower_ascii(const char c)
+{
+ return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c;
+}
+
+char BLI_toupper_ascii(const char c)
+{
+ return (c >= 'a' && c <= 'z') ? c - ('a' - 'A') : c;
+}
+
void BLI_str_tolower_ascii(char *str, const size_t len)
{
size_t i;
for (i = 0; (i < len) && str[i]; i++) {
- if (str[i] >= 'A' && str[i] <= 'Z') {
- str[i] += 'a' - 'A';
- }
+ str[i] = BLI_tolower_ascii(str[i]);
}
}
@@ -930,9 +938,7 @@ void BLI_str_toupper_ascii(char *str, const size_t len)
size_t i;
for (i = 0; (i < len) && str[i]; i++) {
- if (str[i] >= 'a' && str[i] <= 'z') {
- str[i] -= 'a' - 'A';
- }
+ str[i] = BLI_toupper_ascii(str[i]);
}
}
diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_surface_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_surface_lib.glsl
index f85ef4a89a4..0f5290a7c07 100644
--- a/source/blender/draw/engines/eevee/shaders/closure_eval_surface_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/closure_eval_surface_lib.glsl
@@ -309,16 +309,19 @@ vec4 closure_to_rgba(Closure closure)
return vec4(closure.radiance, 1.0 - saturate(avg(closure.transmittance)));
}
-Closure closure_add(Closure cl1, Closure cl2)
+Closure closure_add(inout Closure cl1, inout Closure cl2)
{
Closure cl;
cl.radiance = cl1.radiance + cl2.radiance;
cl.transmittance = cl1.transmittance + cl2.transmittance;
cl.holdout = cl1.holdout + cl2.holdout;
+ /* Make sure each closure is only added once to the result. */
+ cl1 = CLOSURE_DEFAULT;
+ cl2 = CLOSURE_DEFAULT;
return cl;
}
-Closure closure_mix(Closure cl1, Closure cl2, float fac)
+Closure closure_mix(inout Closure cl1, inout Closure cl2, float fac)
{
/* Weights have already been applied. */
return closure_add(cl1, cl2);
diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_volume_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_volume_lib.glsl
index e450b8ad3c8..5e34d654cfd 100644
--- a/source/blender/draw/engines/eevee/shaders/closure_eval_volume_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/closure_eval_volume_lib.glsl
@@ -92,7 +92,7 @@ vec4 closure_to_rgba(Closure closure)
return vec4(0.0);
}
-Closure closure_mix(Closure cl1, Closure cl2, float fac)
+Closure closure_mix(inout Closure cl1, inout Closure cl2, float fac)
{
Closure cl;
cl.absorption = mix(cl1.absorption, cl2.absorption, fac);
@@ -102,7 +102,7 @@ Closure closure_mix(Closure cl1, Closure cl2, float fac)
return cl;
}
-Closure closure_add(Closure cl1, Closure cl2)
+Closure closure_add(inout Closure cl1, inout Closure cl2)
{
Closure cl;
cl.absorption = cl1.absorption + cl2.absorption;
diff --git a/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl
index 9698b5ea6f5..21d347942ca 100644
--- a/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/closure_type_lib.glsl
@@ -87,8 +87,8 @@ Closure closure_eval(ClosureDiffuse diffuse,
ClosureReflection clearcoat,
ClosureRefraction refraction);
-Closure closure_add(Closure cl1, Closure cl2);
-Closure closure_mix(Closure cl1, Closure cl2, float fac);
+Closure closure_add(inout Closure cl1, inout Closure cl2);
+Closure closure_mix(inout Closure cl1, inout Closure cl2, float fac);
float ambient_occlusion_eval(vec3 normal,
float distance,
diff --git a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl
index 1f2f7cb65cc..696e5d4c97b 100644
--- a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl
@@ -112,6 +112,7 @@ GlobalData init_globals(void)
surf.N = -surf.N;
}
# ifdef HAIR_SHADER
+ vec3 V = cameraVec(surf.P);
/* Shade as a cylinder. */
vec3 B = normalize(cross(worldNormal, hairTangent));
float cos_theta;
@@ -125,7 +126,10 @@ GlobalData init_globals(void)
}
float sin_theta = sqrt(max(0.0, 1.0 - cos_theta * cos_theta));
surf.N = safe_normalize(worldNormal * sin_theta + B * cos_theta);
- surf.T = hairTangent;
+ surf.curve_T = -hairTangent;
+ /* Costly, but follows cycles per pixel tangent space (not following curve shape). */
+ surf.curve_B = cross(V, surf.curve_T);
+ surf.curve_N = safe_normalize(cross(surf.curve_T, surf.curve_B));
surf.is_strand = true;
surf.hair_time = hairTime;
surf.hair_thickness = hairThickness;
@@ -134,7 +138,7 @@ GlobalData init_globals(void)
surf.barycentric_coords = hair_resolve_barycentric(hairBary);
# endif
# else
- surf.T = vec3(0.0);
+ surf.curve_T = surf.curve_B = surf.curve_N = vec3(0.0);
surf.is_strand = false;
surf.hair_time = 0.0;
surf.hair_thickness = 0.0;
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl
index 11f93ad0d14..708bd153e84 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_geom_curves_vert.glsl
@@ -18,7 +18,7 @@ void main()
ViewMatrixInverse[3].xyz,
ViewMatrixInverse[2].xyz,
interp.P,
- T,
+ interp.curves_tangent,
interp.curves_binormal,
interp.curves_time,
interp.curves_thickness,
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl
index 06191a5c007..277b2e35d8b 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl
@@ -9,6 +9,7 @@ float g_holdout;
/* The Closure type is never used. Use float as dummy type. */
#define Closure float
+#define CLOSURE_DEFAULT 0.0
/* Sampled closure parameters. */
ClosureDiffuse g_diffuse_data;
diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl
index 0d8644c9901..30b48edaa78 100644
--- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl
+++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_lib.glsl
@@ -42,6 +42,12 @@ void init_globals_curves()
float sin_theta = sqrt(max(0.0, 1.0 - cos_theta * cos_theta));
g_data.N = normalize(interp.N * sin_theta + interp.curves_binormal * cos_theta);
+ /* Costly, but follows cycles per pixel tangent space (not following curve shape). */
+ vec3 V = cameraVec(g_data.P);
+ g_data.curve_T = -interp.curves_tangent;
+ g_data.curve_B = cross(V, g_data.curve_T);
+ g_data.curve_N = safe_normalize(cross(g_data.curve_T, g_data.curve_B));
+
g_data.is_strand = true;
g_data.hair_time = interp.curves_time;
g_data.hair_thickness = interp.curves_thickness;
@@ -94,6 +100,7 @@ void init_interface()
interp.P = vec3(0.0);
interp.N = vec3(0.0);
interp.barycentric_coords = vec2(0.0);
+ interp.curves_tangent = vec3(0.0);
interp.curves_binormal = vec3(0.0);
interp.curves_time = 0.0;
interp.curves_time_width = 0.0;
diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh
index cd297de5719..ccd67360073 100644
--- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh
+++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh
@@ -54,6 +54,7 @@ GPU_SHADER_INTERFACE_INFO(eevee_surf_iface, "interp")
.smooth(Type::VEC3, "P")
.smooth(Type::VEC3, "N")
.smooth(Type::VEC2, "barycentric_coords")
+ .smooth(Type::VEC3, "curves_tangent")
.smooth(Type::VEC3, "curves_binormal")
.smooth(Type::FLOAT, "curves_time")
.smooth(Type::FLOAT, "curves_time_width")
diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc
index fa911037d00..f1b46f8bf86 100644
--- a/source/blender/gpu/intern/gpu_codegen.cc
+++ b/source/blender/gpu/intern/gpu_codegen.cc
@@ -61,24 +61,25 @@ struct GPUCodegenCreateInfo : ShaderCreateInfo {
char var_names[16][8];
blender::Vector<std::array<char, 32>, 16> sampler_names;
- void append_sampler_name(const char name[32])
+ /* Returns the appended name memory location */
+ const char *append_sampler_name(const char name[32])
{
- std::array<char, 32> sampler_name;
- memcpy(sampler_name.data(), name, 32);
- sampler_names.append(sampler_name);
+ auto index = sampler_names.append_and_get_index(std::array<char, 32>());
+ char *name_buffer = sampler_names[index].data();
+ memcpy(name_buffer, name, 32);
+ return name_buffer;
}
};
/** Optional generated interface. */
StageInterfaceInfo *interface_generated = nullptr;
/** Optional name buffer containing names referenced by StringRefNull. */
- NameBuffer *name_buffer = nullptr;
+ NameBuffer name_buffer;
GPUCodegenCreateInfo(const char *name) : ShaderCreateInfo(name){};
~GPUCodegenCreateInfo()
{
delete interface_generated;
- MEM_delete(name_buffer);
};
};
@@ -297,7 +298,6 @@ void GPUCodegen::generate_attribs()
GPUCodegenCreateInfo &info = *create_info;
- info.name_buffer = MEM_new<GPUCodegenCreateInfo::NameBuffer>("info.name_buffer");
info.interface_generated = new StageInterfaceInfo("codegen_iface", "var_attrs");
StageInterfaceInfo &iface = *info.interface_generated;
info.vertex_out(iface);
@@ -311,11 +311,11 @@ void GPUCodegen::generate_attribs()
BLI_assert_msg(0, "Too many attributes");
break;
}
- STRNCPY(info.name_buffer->attr_names[slot], attr->input_name);
- SNPRINTF(info.name_buffer->var_names[slot], "v%d", attr->id);
+ STRNCPY(info.name_buffer.attr_names[slot], attr->input_name);
+ SNPRINTF(info.name_buffer.var_names[slot], "v%d", attr->id);
- blender::StringRefNull attr_name = info.name_buffer->attr_names[slot];
- blender::StringRefNull var_name = info.name_buffer->var_names[slot];
+ blender::StringRefNull attr_name = info.name_buffer.attr_names[slot];
+ blender::StringRefNull var_name = info.name_buffer.var_names[slot];
eGPUType input_type, iface_type;
@@ -357,28 +357,19 @@ void GPUCodegen::generate_resources()
/* Textures. */
LISTBASE_FOREACH (GPUMaterialTexture *, tex, &graph.textures) {
if (tex->colorband) {
- info.name_buffer->append_sampler_name(tex->sampler_name);
- info.sampler(0,
- ImageType::FLOAT_1D_ARRAY,
- info.name_buffer->sampler_names.last().data(),
- Frequency::BATCH);
+ const char *name = info.name_buffer.append_sampler_name(tex->sampler_name);
+ info.sampler(0, ImageType::FLOAT_1D_ARRAY, name, Frequency::BATCH);
}
else if (tex->tiled_mapping_name[0] != '\0') {
- info.name_buffer->append_sampler_name(tex->sampler_name);
- info.sampler(0,
- ImageType::FLOAT_2D_ARRAY,
- info.name_buffer->sampler_names.last().data(),
- Frequency::BATCH);
- info.name_buffer->append_sampler_name(tex->tiled_mapping_name);
- info.sampler(0,
- ImageType::FLOAT_1D_ARRAY,
- info.name_buffer->sampler_names.last().data(),
- Frequency::BATCH);
+ const char *name = info.name_buffer.append_sampler_name(tex->sampler_name);
+ info.sampler(0, ImageType::FLOAT_2D_ARRAY, name, Frequency::BATCH);
+
+ const char *name_mapping = info.name_buffer.append_sampler_name(tex->tiled_mapping_name);
+ info.sampler(0, ImageType::FLOAT_1D_ARRAY, name_mapping, Frequency::BATCH);
}
else {
- info.name_buffer->append_sampler_name(tex->sampler_name);
- info.sampler(
- 0, ImageType::FLOAT_2D, info.name_buffer->sampler_names.last().data(), Frequency::BATCH);
+ const char *name = info.name_buffer.append_sampler_name(tex->sampler_name);
+ info.sampler(0, ImageType::FLOAT_2D, name, Frequency::BATCH);
}
}
diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c
index bc7ace792bb..b3a091ffbb0 100644
--- a/source/blender/gpu/intern/gpu_node_graph.c
+++ b/source/blender/gpu/intern/gpu_node_graph.c
@@ -611,7 +611,7 @@ bool GPU_link(GPUMaterial *mat, const char *name, ...)
va_start(params, name);
for (i = 0; i < function->totparam; i++) {
- if (function->paramqual[i] != FUNCTION_QUAL_IN) {
+ if (function->paramqual[i] == FUNCTION_QUAL_OUT) {
linkptr = va_arg(params, GPUNodeLink **);
gpu_node_output(node, function->paramtype[i], linkptr);
}
@@ -669,7 +669,7 @@ static bool gpu_stack_link_v(GPUMaterial *material,
}
for (i = 0; i < function->totparam; i++) {
- if (function->paramqual[i] != FUNCTION_QUAL_IN) {
+ if (function->paramqual[i] == FUNCTION_QUAL_OUT) {
if (totout == 0) {
linkptr = va_arg(params, GPUNodeLink **);
gpu_node_output(node, function->paramtype[i], linkptr);
diff --git a/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl
index 5c97eada77d..6091a5c834a 100644
--- a/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl
@@ -191,8 +191,8 @@ struct GlobalData {
vec3 N;
/** Geometric Normal. */
vec3 Ng;
- /** Surface default Tangent. */
- vec3 T;
+ /** Curve Tangent Space. */
+ vec3 curve_T, curve_B, curve_N;
/** Barycentric coordinates. */
vec2 barycentric_coords;
vec3 barycentric_dists;
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_add_shader.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_add_shader.glsl
index 99117400c57..3f42b6d9094 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_add_shader.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_add_shader.glsl
@@ -1,4 +1,4 @@
-void node_add_shader(Closure shader1, Closure shader2, out Closure shader)
+void node_add_shader(inout Closure shader1, inout Closure shader2, out Closure shader)
{
shader = closure_add(shader1, shader2);
}
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl
index 5e86a4577ee..4c9ff31622f 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_geometry.glsl
@@ -18,7 +18,7 @@ void node_geometry(vec3 orco,
true_normal = g_data.Ng;
if (g_data.is_strand) {
- tangent = g_data.T;
+ tangent = g_data.curve_T;
}
else {
tangent_orco_z(orco, orco);
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl
index 7bf8795495a..b24f9ab65f0 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_hair.glsl
@@ -40,7 +40,7 @@ void node_bsdf_hair_principled(vec4 color,
hair_data.color = color.rgb;
hair_data.offset = offset;
hair_data.roughness = vec2(0.0);
- hair_data.T = g_data.T;
+ hair_data.T = g_data.curve_B;
result = closure_eval(hair_data);
}
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl
index 8e878b6e14b..61458b05c86 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl
@@ -5,14 +5,14 @@ void node_hair_info(float hair_length,
out float intercept,
out float out_length,
out float thickness,
- out vec3 tangent,
+ out vec3 normal,
out float random)
{
is_strand = float(g_data.is_strand);
intercept = g_data.hair_time;
thickness = g_data.hair_thickness;
out_length = hair_length;
- tangent = g_data.T;
+ normal = g_data.curve_N;
/* TODO: could be precomputed per strand instead. */
random = wang_hash_noise(uint(g_data.hair_strand_id));
}
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_mix_shader.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_mix_shader.glsl
index c303d21d7c1..00cfba3ca12 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_mix_shader.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_mix_shader.glsl
@@ -1,4 +1,4 @@
-void node_mix_shader(float fac, Closure shader1, Closure shader2, out Closure shader)
+void node_mix_shader(float fac, inout Closure shader1, inout Closure shader2, out Closure shader)
{
shader = closure_mix(shader1, shader2, fac);
}
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 9948aaac5da..2281d8d85b3 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -1394,12 +1394,10 @@ static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *pa
const char *name = echan->m->name.c_str();
const char *end = name + strlen(name);
const char *token;
- char tokenbuf[EXR_TOT_MAXNAME];
- int len;
/* some multilayers have the combined buffer with names A B G R saved */
if (name[1] == 0) {
- echan->chan_id = name[0];
+ echan->chan_id = BLI_toupper_ascii(name[0]);
layname[0] = '\0';
if (ELEM(name[0], 'R', 'G', 'B', 'A')) {
@@ -1416,13 +1414,17 @@ static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *pa
}
/* last token is channel identifier */
- len = imb_exr_split_token(name, end, &token);
+ size_t len = imb_exr_split_token(name, end, &token);
if (len == 0) {
printf("multilayer read: bad channel name: %s\n", name);
return 0;
}
+
+ char channelname[EXR_TOT_MAXNAME];
+ BLI_strncpy(channelname, token, std::min(len + 1, sizeof(channelname)));
+
if (len == 1) {
- echan->chan_id = token[0];
+ echan->chan_id = BLI_toupper_ascii(channelname[0]);
}
else if (len > 1) {
bool ok = false;
@@ -1436,36 +1438,35 @@ static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *pa
*
* Here we do some magic to distinguish such cases.
*/
- if (ELEM(token[1], 'X', 'Y', 'Z') || ELEM(token[1], 'R', 'G', 'B') ||
- ELEM(token[1], 'U', 'V', 'A')) {
- echan->chan_id = token[1];
+ const char chan_id = BLI_toupper_ascii(channelname[1]);
+ if (ELEM(chan_id, 'X', 'Y', 'Z', 'R', 'G', 'B', 'U', 'V', 'A')) {
+ echan->chan_id = chan_id;
ok = true;
}
}
- else if (BLI_strcaseeq(token, "red")) {
+ else if (BLI_strcaseeq(channelname, "red")) {
echan->chan_id = 'R';
ok = true;
}
- else if (BLI_strcaseeq(token, "green")) {
+ else if (BLI_strcaseeq(channelname, "green")) {
echan->chan_id = 'G';
ok = true;
}
- else if (BLI_strcaseeq(token, "blue")) {
+ else if (BLI_strcaseeq(channelname, "blue")) {
echan->chan_id = 'B';
ok = true;
}
- else if (BLI_strcaseeq(token, "alpha")) {
+ else if (BLI_strcaseeq(channelname, "alpha")) {
echan->chan_id = 'A';
ok = true;
}
- else if (BLI_strcaseeq(token, "depth")) {
+ else if (BLI_strcaseeq(channelname, "depth")) {
echan->chan_id = 'Z';
ok = true;
}
if (ok == false) {
- BLI_strncpy(tokenbuf, token, std::min(len + 1, EXR_TOT_MAXNAME));
- printf("multilayer read: unknown channel token: %s\n", tokenbuf);
+ printf("multilayer read: unknown channel token: %s\n", channelname);
return 0;
}
}