htrdr

Solving radiative transfer in heterogeneous media
git clone git://git.meso-star.fr/htrdr.git
Log | Files | Refs | README | LICENSE

commit 7184c1f258ea5c9b55d92ba9524ccae44cdfb92c
parent 4abbb2e19283261047025c0b9e48586da2bd3fc3
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 16 Apr 2020 16:40:06 +0200

Small refactoring of the cie_xyz create function

Diffstat:
Msrc/htrdr_cie_xyz.c | 120+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
1 file changed, 68 insertions(+), 52 deletions(-)

diff --git a/src/htrdr_cie_xyz.c b/src/htrdr_cie_xyz.c @@ -13,7 +13,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#define _POSIX_C_SOURCE 200112L +#define _POSIX_C_SOURCE 200112L /* nextafter */ #include "htrdr.h" #include "htrdr_c.h" @@ -122,65 +122,32 @@ sample_cie_xyz return wlen; } - -static void -release_cie_xyz(ref_T* ref) +static res_T +setup_cie_xyz + (struct htrdr_cie_xyz* cie, + const char* func_name, + const double range[2], + const size_t nbands) { - struct htrdr_cie_xyz* cie = NULL; - ASSERT(ref); - cie = CONTAINER_OF(ref, struct htrdr_cie_xyz, ref); - darray_double_release(&cie->cdf_X); - darray_double_release(&cie->cdf_Y); - darray_double_release(&cie->cdf_Z); - MEM_RM(cie->htrdr->allocator, cie); -} - -/******************************************************************************* - * Local functions - ******************************************************************************/ -res_T -htrdr_cie_xyz_create - (struct htrdr* htrdr, - const double range[2], /* Must be included in [380, 780] nanometers */ - const size_t nbands, /* # bands used to discretisze the CIE tristimulus */ - struct htrdr_cie_xyz** out_cie) -{ - enum { X, Y, Z }; /* Helper constant */ - struct htrdr_cie_xyz* cie = NULL; double* pdf[3] = {NULL, NULL, NULL}; double* cdf[3] = {NULL, NULL, NULL}; double sum[3] = {0,0,0}; size_t i; res_T res = RES_OK; - ASSERT(htrdr && range && nbands && out_cie); + + ASSERT(cie && func_name && range && nbands); ASSERT(range[0] >= HTRDR_CIE_XYZ_RANGE_DEFAULT[0]); ASSERT(range[1] <= HTRDR_CIE_XYZ_RANGE_DEFAULT[1]); ASSERT(range[0] < range[1]); - cie = MEM_CALLOC(htrdr->allocator, 1, sizeof(*cie)); - if(!cie) { - res = RES_MEM_ERR; - htrdr_log_err(htrdr, - "%s: could not allocate the CIE XYZ data structure -- %s.\n", - FUNC_NAME, res_to_cstr(res)); - goto error; - } - ref_init(&cie->ref); - cie->htrdr = htrdr; - cie->range[0] = range[0]; - cie->range[1] = range[1]; - darray_double_init(htrdr->allocator, &cie->cdf_X); - darray_double_init(htrdr->allocator, &cie->cdf_Y); - darray_double_init(htrdr->allocator, &cie->cdf_Z); - /* Allocate and reset the memory space for the tristimulus CDF */ #define SETUP_STIMULUS(Stimulus) { \ res = darray_double_resize(&cie->cdf_ ## Stimulus, nbands); \ if(res != RES_OK) { \ - htrdr_log_err(htrdr, \ + htrdr_log_err(cie->htrdr, \ "%s: Could not reserve the memory space for the CDF " \ - "of the "STR(X)" stimulus -- %s.\n", FUNC_NAME, res_to_cstr(res)); \ + "of the "STR(X)" stimulus -- %s.\n", func_name, res_to_cstr(res)); \ goto error; \ } \ cdf[Stimulus] = darray_double_data_get(&cie->cdf_ ## Stimulus); \ @@ -193,6 +160,8 @@ htrdr_cie_xyz_create #undef SETUP_STIMULUS /* Compute the *unormalized* pdf of the tristimulus */ + cie->range[0] = range[0]; + cie->range[1] = range[1]; cie->band_len = (range[1] - range[0]) / (double)nbands; FOR_EACH(i, 0, nbands) { const double lambda_lo = range[0] + (double)i * cie->band_len; @@ -220,26 +189,73 @@ htrdr_cie_xyz_create cdf[X][i] = pdf[X][i] + cdf[X][i-1]; cdf[Y][i] = pdf[Y][i] + cdf[Y][i-1]; cdf[Z][i] = pdf[Z][i] + cdf[Z][i-1]; + ASSERT(cdf[X][i] >= cdf[X][i-1]); + ASSERT(cdf[Y][i] >= cdf[Y][i-1]); + ASSERT(cdf[Z][i] >= cdf[Z][i-1]); } } ASSERT(eq_eps(cdf[X][nbands-1], 1, 1.e-6)); ASSERT(eq_eps(cdf[Y][nbands-1], 1, 1.e-6)); ASSERT(eq_eps(cdf[Z][nbands-1], 1, 1.e-6)); -#ifndef NDEBUG - FOR_EACH(i, 1, nbands) { - ASSERT(cdf[X][i] >= cdf[X][i-1]); - ASSERT(cdf[Y][i] >= cdf[Y][i-1]); - ASSERT(cdf[Z][i] >= cdf[Z][i-1]); - } -#endif - /* Handle numerical issue */ cdf[X][nbands-1] = 1.0; cdf[Y][nbands-1] = 1.0; cdf[Z][nbands-1] = 1.0; exit: + return res; +error: + darray_double_clear(&cie->cdf_X); + darray_double_clear(&cie->cdf_Y); + darray_double_clear(&cie->cdf_Z); + goto exit; +} + +static void +release_cie_xyz(ref_T* ref) +{ + struct htrdr_cie_xyz* cie = NULL; + ASSERT(ref); + cie = CONTAINER_OF(ref, struct htrdr_cie_xyz, ref); + darray_double_release(&cie->cdf_X); + darray_double_release(&cie->cdf_Y); + darray_double_release(&cie->cdf_Z); + MEM_RM(cie->htrdr->allocator, cie); +} + +/******************************************************************************* + * Local functions + ******************************************************************************/ +res_T +htrdr_cie_xyz_create + (struct htrdr* htrdr, + const double range[2], /* Must be included in [380, 780] nanometers */ + const size_t nbands, /* # bands used to discretisze the CIE tristimulus */ + struct htrdr_cie_xyz** out_cie) +{ + struct htrdr_cie_xyz* cie = NULL; + res_T res = RES_OK; + ASSERT(htrdr && range && nbands && out_cie); + + cie = MEM_CALLOC(htrdr->allocator, 1, sizeof(*cie)); + if(!cie) { + res = RES_MEM_ERR; + htrdr_log_err(htrdr, + "%s: could not allocate the CIE XYZ data structure -- %s.\n", + FUNC_NAME, res_to_cstr(res)); + goto error; + } + ref_init(&cie->ref); + cie->htrdr = htrdr; + darray_double_init(htrdr->allocator, &cie->cdf_X); + darray_double_init(htrdr->allocator, &cie->cdf_Y); + darray_double_init(htrdr->allocator, &cie->cdf_Z); + + res = setup_cie_xyz(cie, FUNC_NAME, range, nbands); + if(res != RES_OK) goto error; + +exit: *out_cie = cie; return res; error: