From 8332d652eac5b46d8b8b02b25d47aa5355ef31cd Mon Sep 17 00:00:00 2001 From: admin Date: Sun, 3 Aug 2025 18:25:31 +0200 Subject: added schott json --- src/glamac/glass_data.c | 221 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 211 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/glamac/glass_data.c b/src/glamac/glass_data.c index 7c52d08..794fa7b 100644 --- a/src/glamac/glass_data.c +++ b/src/glamac/glass_data.c @@ -12,9 +12,17 @@ */ #include "glamacdef.h" #include "glass_data.h" +#include +#include +#include -// Sample glass data -static const Glass glasses[] = { +// Dynamic glass data storage +static Glass* glasses = NULL; +static u32 glass_count = 0; +static b32 using_json_data = 0; + +// Fallback sample glass data (SCHOTT glasses for testing) +static const Glass default_glasses[] = { {"FK51A", 81.61f, 1.4866f}, {"F2", 36.37f, 1.6200f}, {"SF10", 28.41f, 1.7283f}, @@ -28,16 +36,16 @@ static const Glass glasses[] = { {"N-BK7", 64.17f, 1.5168f} }; -#define GLASS_COUNT (sizeof(glasses) / sizeof(glasses[0])) +#define DEFAULT_GLASS_COUNT (sizeof(default_glasses) / sizeof(default_glasses[0])) // Get number of glasses in the catalog u32 get_glass_count(void) { - return GLASS_COUNT; + return glass_count; } // Get glass at index const Glass* get_glass(u32 index) { - if (index < GLASS_COUNT) { + if (index < glass_count) { return &glasses[index]; } return NULL; @@ -45,7 +53,7 @@ const Glass* get_glass(u32 index) { // Get glass name const byte* get_glass_name(u32 index) { - if (index < GLASS_COUNT) { + if (index < glass_count) { return glasses[index].name; } return NULL; @@ -53,12 +61,18 @@ const byte* get_glass_name(u32 index) { // Find data range in glass catalog void find_glass_data_range(f32 *minAbbe, f32 *maxAbbe, f32 *minRI, f32 *maxRI) { + if (glass_count == 0) { + *minAbbe = *maxAbbe = 50.0f; + *minRI = *maxRI = 1.5f; + return; + } + *minAbbe = glasses[0].abbeNumber; *maxAbbe = glasses[0].abbeNumber; *minRI = glasses[0].refractiveIndex; *maxRI = glasses[0].refractiveIndex; - for (u32 i = 1; i < GLASS_COUNT; i++) { + for (u32 i = 1; i < glass_count; i++) { if (glasses[i].abbeNumber < *minAbbe) *minAbbe = glasses[i].abbeNumber; if (glasses[i].abbeNumber > *maxAbbe) *maxAbbe = glasses[i].abbeNumber; if (glasses[i].refractiveIndex < *minRI) *minRI = glasses[i].refractiveIndex; @@ -74,8 +88,195 @@ void find_glass_data_range(f32 *minAbbe, f32 *maxAbbe, f32 *minRI, f32 *maxRI) { *maxRI += riMargin; } -// Initialize glass data - placeholder for future expansion +// Simple JSON string helper functions +static byte* find_json_string(const byte* json, const byte* key) { + byte search_pattern[256]; + snprintf((char*)search_pattern, sizeof(search_pattern), "\"%s\":", (char*)key); + + byte* found = (byte*)strstr((char*)json, (char*)search_pattern); + if (!found) return NULL; + + // Move past the key and find the opening quote + found = (byte*)strchr((char*)found + strlen((char*)search_pattern), '"'); + if (!found) return NULL; + found++; // Move past opening quote + + // Find closing quote + byte* end = (byte*)strchr((char*)found, '"'); + if (!end) return NULL; + + // Allocate and copy string + size_t len = end - found; + byte* result = (byte*)malloc(len + 1); + if (result) { + memcpy(result, found, len); + result[len] = '\0'; + } + return result; +} + +static f32 find_json_number(const byte* json, const byte* key) { + byte search_pattern[256]; + snprintf((char*)search_pattern, sizeof(search_pattern), "\"%s\":", (char*)key); + + byte* found = (byte*)strstr((char*)json, (char*)search_pattern); + if (!found) return 0.0f; + + // Move past the key and find the number + found += strlen((char*)search_pattern); + while (*found == ' ' || *found == '\t') found++; // Skip whitespace + + return (f32)atof((char*)found); +} + +// Load glasses from JSON file +b32 load_glasses_from_json(const byte* json_path, const byte* manufacturer_filter) { + FILE* file = fopen((char*)json_path, "r"); + if (!file) { + printf("Warning: Could not open JSON file: %s\n", json_path); + return 0; + } + + // Get file size + fseek(file, 0, SEEK_END); + long file_size = ftell(file); + fseek(file, 0, SEEK_SET); + + // Read entire file + byte* json_content = (byte*)malloc(file_size + 1); + if (!json_content) { + fclose(file); + return 0; + } + + fread(json_content, 1, file_size, file); + json_content[file_size] = '\0'; + fclose(file); + + // Find the manufacturer section + byte manufacturer_key[256]; + snprintf((char*)manufacturer_key, sizeof(manufacturer_key), "\"%s\":", (char*)manufacturer_filter); + + byte* mfg_section = (byte*)strstr((char*)json_content, (char*)manufacturer_key); + if (!mfg_section) { + printf("Warning: Manufacturer '%s' not found in JSON\n", manufacturer_filter); + free(json_content); + return 0; + } + + // Find the glasses array within this manufacturer + byte* glasses_array = (byte*)strstr((char*)mfg_section, "\"glasses\":"); + if (!glasses_array) { + printf("Warning: No glasses array found for manufacturer '%s'\n", manufacturer_filter); + free(json_content); + return 0; + } + + // Find opening bracket of glasses array + byte* array_start = (byte*)strchr((char*)glasses_array, '['); + if (!array_start) { + free(json_content); + return 0; + } + array_start++; + + // Count glasses by counting glass objects + u32 count = 0; + byte* pos = array_start; + while ((pos = (byte*)strchr((char*)pos, '{')) != NULL) { + count++; + pos++; + } + + if (count == 0) { + free(json_content); + return 0; + } + + // Allocate glasses array + if (glasses) { + free(glasses); + } + glasses = (Glass*)malloc(count * sizeof(Glass)); + if (!glasses) { + free(json_content); + return 0; + } + + // Parse each glass + glass_count = 0; + pos = array_start; + + while (glass_count < count && (pos = (byte*)strchr((char*)pos, '{')) != NULL) { + // Find end of this glass object + byte* obj_end = (byte*)strchr((char*)pos, '}'); + if (!obj_end) break; + + // Extract glass data from this object + byte* name = find_json_string(pos, (byte*)"name"); + f32 nd = find_json_number(pos, (byte*)"nd"); + f32 vd = find_json_number(pos, (byte*)"vd"); + + if (name && nd > 0.0f && vd > 0.0f) { + // Copy name (truncate if too long) + strncpy((char*)glasses[glass_count].name, (char*)name, sizeof(glasses[glass_count].name) - 1); + glasses[glass_count].name[sizeof(glasses[glass_count].name) - 1] = '\0'; + glasses[glass_count].abbeNumber = vd; + glasses[glass_count].refractiveIndex = nd; + glass_count++; + } + + if (name) free(name); + pos = obj_end + 1; + } + + free(json_content); + using_json_data = (glass_count > 0); + + printf("Loaded %u %s glasses from JSON\n", glass_count, manufacturer_filter); + return using_json_data; +} + +// Try multiple JSON file paths for cross-platform compatibility +static b32 try_load_json_with_fallbacks(const byte* manufacturer_filter) { + // List of possible JSON file paths to try + const byte* json_paths[] = { + (byte*)"data/json/glasses.json", // Linux style + (byte*)"data\\json\\glasses.json", // Windows style + (byte*)"glasses.json", // Current directory + (byte*)"..\\data\\json\\glasses.json", // Windows relative + (byte*)"../data/json/glasses.json", // Linux relative + NULL + }; + + for (int i = 0; json_paths[i] != NULL; i++) { + printf("Trying JSON path: %s\n", json_paths[i]); + if (load_glasses_from_json(json_paths[i], manufacturer_filter)) { + return 1; // Success + } + } + + return 0; // All paths failed +} + +// Initialize glass data void initialize_glass_data(void) { - // Currently using static data, but this could be expanded - // to load data from files in the future + // Try to load SCHOTT glasses from JSON with multiple path attempts + if (!try_load_json_with_fallbacks((byte*)"SCHOTT")) { + // Fallback to default static data + printf("JSON loading failed, using fallback glass data\n"); + + if (glasses) { + free(glasses); + } + + glass_count = DEFAULT_GLASS_COUNT; + glasses = (Glass*)malloc(glass_count * sizeof(Glass)); + if (glasses) { + memcpy(glasses, default_glasses, glass_count * sizeof(Glass)); + using_json_data = 0; + } else { + glass_count = 0; + } + } } -- cgit v1.2.3