From 97222519debc140165fa09e20fce39be910f6bc0 Mon Sep 17 00:00:00 2001 From: Jesse Yurkovich Date: Fri, 28 Apr 2023 23:29:04 +0200 Subject: [PATCH] Fix #106945: IES file parsing failures There were two issues here preventing the proper display of the IES files in question. The primary one was that these lights are actually vertical. Their profiles actually point upwards from 90deg to 180deg but our parser was trying hard to adjust it to start at 0deg incorrectly. Lastly, the files in question ended with the parser in the `eof` state - they are "missing" the final carriage return that other IES files tend to have but other viewers don't seem to mind. Change the `eof` check instead for a better one that will indicate if any parsing errors occurred along the way. Pull Request: https://projects.blender.org/blender/blender/pulls/107320 --- intern/cycles/kernel/svm/ies.h | 4 ++-- intern/cycles/util/ies.cpp | 24 ++++++++++++++---------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/intern/cycles/kernel/svm/ies.h b/intern/cycles/kernel/svm/ies.h index b40e04df62c..9d723e2c865 100644 --- a/intern/cycles/kernel/svm/ies.h +++ b/intern/cycles/kernel/svm/ies.h @@ -43,10 +43,10 @@ ccl_device_inline float kernel_ies_interp(KernelGlobals kg, int slot, float h_an #define IES_LOOKUP_ANGLE_V(v) kernel_data_fetch(ies, ofs + h_num + (v)) /* Check whether the angle is within the bounds of the IES texture. */ - if (v_angle >= IES_LOOKUP_ANGLE_V(v_num - 1)) { + if (v_angle < IES_LOOKUP_ANGLE_V(0) || v_angle >= IES_LOOKUP_ANGLE_V(v_num - 1)) { return 0.0f; } - kernel_assert(v_angle >= IES_LOOKUP_ANGLE_V(0)); + kernel_assert(h_angle >= IES_LOOKUP_ANGLE_H(0)); kernel_assert(h_angle <= IES_LOOKUP_ANGLE_H(h_num - 1)); diff --git a/intern/cycles/util/ies.cpp b/intern/cycles/util/ies.cpp index 894a6a44700..b2b31eddd68 100644 --- a/intern/cycles/util/ies.cpp +++ b/intern/cycles/util/ies.cpp @@ -64,8 +64,9 @@ class IESTextParser { public: vector text; char *data; + bool error; - IESTextParser(const string &str) : text(str.begin(), str.end()) + IESTextParser(const string &str) : text(str.begin(), str.end()), error(false) { std::replace(text.begin(), text.end(), ',', ' '); data = strstr(&text[0], "\nTILT="); @@ -76,15 +77,22 @@ class IESTextParser { return (data == NULL) || (data[0] == '\0'); } + bool has_error() + { + return error; + } + double get_double() { if (eof()) { + error = true; return 0.0; } char *old_data = data; double val = strtod(data, &data); if (data == old_data) { data = NULL; + error = true; return 0.0; } return val; @@ -93,12 +101,14 @@ class IESTextParser { long get_long() { if (eof()) { + error = true; return 0; } char *old_data = data; long val = strtol(data, &data, 10); if (data == old_data) { data = NULL; + error = true; return 0; } return val; @@ -191,7 +201,7 @@ bool IESFile::parse(const string &ies) } } - return !parser.eof(); + return !parser.has_error(); } bool IESFile::process_type_b() @@ -340,13 +350,7 @@ bool IESFile::process_type_c() float v_first = v_angles[0], v_last = v_angles[v_angles.size() - 1]; if (v_first == 90.0f) { - if (v_last == 180.0f) { - /* Flip to ensure that vertical angles always start at 0°. */ - for (int i = 0; i < v_angles.size(); i++) { - v_angles[i] = 180.0f - v_angles[i]; - } - } - else { + if (v_last != 180.0f) { return false; } } @@ -375,7 +379,7 @@ bool IESFile::process() } } - assert(v_angles[0] == 0.0f); + assert(v_angles[0] == 0.0f || v_angles[0] == 90.0f); assert(h_angles[0] == 0.0f); assert(h_angles[h_angles.size() - 1] == 360.0f);