sphin_btdf.c (6962B)
1 /* Copyright (C) 2024-2026 Centre National de la Recherche Scientifique 2 * Copyright (C) 2024-2026 Clermont Auvergne INP 3 * Copyright (C) 2024-2026 INSA Lyon 4 * Copyright (C) 2024-2026 Institut Mines Télécom Albi-Carmaux 5 * Copyright (C) 2024-2026 Institut National Polytechnique de Toulouse 6 * Copyright (C) 2024-2026 |Méso|Star> (contact@meso-star.com) 7 * Copyright (C) 2024-2026 PhotonLyX (info@photonlyx.com) 8 * Copyright (C) 2024-2026 Université de Lorraine 9 * Copyright (C) 2024-2026 Université Paul Sabatier 10 * Copyright (C) 2024-2026 Université Toulouse - Jean Jaurès 11 * 12 * This program is free software: you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation, either version 3 of the License, or 15 * (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 24 25 #define _POSIX_C_SOURCE 200112L /* for strtok_r support */ 26 27 #include "sphin.h" 28 #include "sphin_c.h" 29 #include "sphin_btdf.h" 30 #include "sphin_config.h" 31 #include "sphin_spectral_property.h" 32 33 #include <rsys/cstr.h> 34 #include <rsys/mem_allocator.h> 35 #include <rsys/ref_count.h> 36 #include <rsys/rsys.h> 37 #include <rsys/text_reader.h> 38 39 struct sphin_btdf { 40 enum sphin_btdf_direction_distribution direction_distribution; 41 enum sphin_btdf_transmissivity_type transmissivity_type; /* Constant, Frensel */ 42 struct sphin_spectral_property* transmissivity; /* Only used if reflectivity is 43 * a constant */ 44 struct sphin* sphin; 45 ref_T ref; 46 }; 47 48 /******************************************************************************* 49 * Helper functions 50 ******************************************************************************/ 51 static res_T 52 btdf_create 53 (struct sphin* sphin, 54 struct sphin_btdf** out_btdf) 55 { 56 struct sphin_btdf* btdf = NULL; 57 res_T res = RES_OK; 58 59 ASSERT(NULL != sphin); 60 ASSERT(NULL != out_btdf); 61 62 btdf = MEM_CALLOC(sphin->allocator, 1, sizeof(struct sphin_btdf)); 63 if (NULL == btdf) { res = RES_MEM_ERR; goto error; } 64 ref_init(&btdf->ref); 65 SPHIN(ref_get(sphin)); 66 btdf->sphin = sphin; 67 btdf->transmissivity_type = SPHIN_BTDF_TRANSMISSIVITY_NONE__; 68 btdf->direction_distribution = SPHIN_BTDF_DIRECTION_NONE__; 69 btdf->transmissivity = NULL; 70 71 exit: 72 *out_btdf = btdf; 73 return res; 74 error: 75 if (NULL != btdf) { 76 SPHIN(btdf_ref_put(btdf)); 77 btdf = NULL; 78 } 79 goto exit; 80 } 81 82 static void 83 release_btdf 84 (ref_T* address) 85 { 86 struct sphin_btdf* btdf = NULL; 87 struct sphin* sphin = NULL; 88 89 ASSERT(NULL != address); 90 91 btdf = CONTAINER_OF(address, struct sphin_btdf, ref); 92 sphin = btdf->sphin; 93 if (NULL != btdf->transmissivity) { 94 SPHIN(spectral_property_ref_put(btdf->transmissivity)); 95 } 96 MEM_RM(sphin->allocator, btdf); 97 SPHIN(ref_put(sphin)); 98 } 99 100 /******************************************************************************* 101 * Local functions 102 ******************************************************************************/ 103 res_T 104 parse_btdf 105 (struct sphin* sphin, 106 struct txtrdr* txtrdr, 107 char* value, 108 struct sphin_btdf** out_btdf) 109 { 110 char* btdf_type = NULL; 111 char* str_transmissivity = NULL; 112 char* token_ptr = NULL; 113 char* filename = NULL; 114 struct sphin_btdf* btdf = NULL; 115 res_T res = RES_OK; 116 117 ASSERT(NULL != sphin); 118 ASSERT(NULL != txtrdr); 119 ASSERT(NULL != out_btdf); 120 121 if (NULL == value) { res = RES_BAD_ARG; goto error; } 122 123 res = btdf_create(sphin, &btdf); 124 if (RES_OK != res) { goto error; } 125 /* Parse btdf type */ 126 btdf_type = strtok_r(value, " \t", &token_ptr); 127 if (NULL == btdf_type){ res = RES_BAD_ARG; goto error; } 128 if (0 == strcmp(btdf_type, "LAMBERT")) { 129 btdf->direction_distribution = SPHIN_BTDF_DIRECTION_LAMBERT; 130 } 131 else if (0 == strcmp(btdf_type, "SNELL_DIELECTRIC")) { 132 btdf->direction_distribution = SPHIN_BTDF_DIRECTION_SNELL_DIELECTRIC; 133 } 134 else if (0 == strcmp(btdf_type, "KEEP_CURRENT_DIR")) { 135 btdf->direction_distribution = SPHIN_BTDF_DIRECTION_KEEP_CURRENT_DIR; 136 } 137 else { res = RES_BAD_ARG; goto error; } 138 139 /* Parse transmissivity value */ 140 str_transmissivity = strtok_r(NULL, " \t", &token_ptr); 141 if (NULL == str_transmissivity){ res = RES_BAD_ARG; goto error; } 142 143 if (0 == strcmp(str_transmissivity, "FRESNEL_DIELECTRIC")) { 144 btdf->transmissivity_type = SPHIN_BTDF_TRANSMISSIVITY_FRESNEL_DIELECTRIC; 145 } 146 else if (0 == strcmp(str_transmissivity, "FRESNEL_DIELECTRIC_CONDUCTOR")) { 147 btdf->transmissivity_type 148 = SPHIN_BTDF_TRANSMISSIVITY_FRESNEL_DIELECTRIC_CONDUCTOR; 149 } 150 else { 151 filename = trim_keyword(str_transmissivity); 152 if (NULL == filename) { res = RES_BAD_ARG; goto error; } 153 154 res = parse_spectral_property(sphin, filename, &btdf->transmissivity); 155 if (RES_OK != res) { goto error; } 156 157 btdf->transmissivity_type = SPHIN_BTDF_TRANSMISSIVITY_TABULATED; 158 } 159 160 res = txtrdr_read_line(txtrdr); 161 if (RES_OK != res) { goto error; } 162 163 exit: 164 *out_btdf = btdf; 165 return res; 166 error: 167 if (btdf != NULL){ 168 SPHIN(btdf_ref_put(btdf)); 169 btdf = NULL; 170 } 171 goto exit; 172 } 173 174 /******************************************************************************* 175 * Exported functions 176 ******************************************************************************/ 177 res_T 178 sphin_btdf_ref_get 179 (struct sphin_btdf* btdf) 180 { 181 if (NULL == btdf) { 182 return RES_BAD_ARG; 183 } 184 ref_get(&btdf->ref); 185 return RES_OK; 186 } 187 188 res_T 189 sphin_btdf_ref_put 190 (struct sphin_btdf* btdf) 191 { 192 if (NULL == btdf) { 193 return RES_BAD_ARG; 194 } 195 ref_put(&btdf->ref, release_btdf); 196 return RES_OK; 197 } 198 199 res_T 200 sphin_btdf_get_direction_distribution 201 (struct sphin_btdf* btdf, 202 enum sphin_btdf_direction_distribution* direction_distribution) 203 { 204 res_T res = RES_OK; 205 206 if (NULL == btdf || NULL == direction_distribution) { 207 return RES_BAD_ARG; 208 } 209 210 *direction_distribution = btdf->direction_distribution; 211 return res; 212 } 213 214 res_T 215 sphin_btdf_get_transmissivity_type 216 (struct sphin_btdf* btdf, 217 enum sphin_btdf_transmissivity_type* transmissivity_type) 218 { 219 res_T res = RES_OK; 220 221 if (NULL == btdf || NULL == transmissivity_type) { 222 return RES_BAD_ARG; 223 } 224 225 *transmissivity_type= btdf->transmissivity_type; 226 return res; 227 } 228 229 res_T 230 sphin_btdf_get_transmissivity_value 231 (struct sphin_btdf* btdf, 232 struct sphin_spectral_property** transmissivity) 233 { 234 res_T res = RES_OK; 235 236 if (NULL == btdf || NULL == transmissivity) { 237 return RES_BAD_ARG; 238 } 239 240 /* Not defined for Fresnel reflectivities types */ 241 if (SPHIN_BTDF_TRANSMISSIVITY_TABULATED != btdf->transmissivity_type) { 242 return RES_BAD_ARG; 243 } 244 245 *transmissivity = btdf->transmissivity; 246 247 return res; 248 }