const gdouble getDouble (JsonReader * reader, const gchar * member_name) { json_reader_read_member (reader, member_name); double value = json_reader_get_double_value (reader); json_reader_end_member (reader); return value; }
/* Save key/values on the table in the stack if the value is an * object or an array, it calls recursively the function again. * * @param L, pointer to the L with nil on top of it; * @param reader, pointed to the first element of main object; * * returns: the table in the stack with all json values */ static void build_table_from_json_reader (lua_State *L, JsonReader *reader) { const GError *err = json_reader_get_error (reader); if (err != NULL) { GRL_WARNING ("Error when building json: %s", err->message); return; } if (lua_isnil (L, -1)) { /* In the first execution of this recursive call, the main json object * does not have a member name. The nil is in the top of the stack and * it shall be converted to the table with json content */ lua_pop (L, 1); } else if (lua_istable (L, -1)) { const gchar *member_name = json_reader_get_member_name (reader); if (member_name) lua_pushstring (L, member_name); } else if (!lua_isnumber (L, -1)) { GRL_DEBUG ("getting value to either table or array"); return; } if (json_reader_is_object (reader)) { guint index_member = 0; guint num_members = json_reader_count_members (reader); lua_createtable (L, num_members, 0); for (index_member = 0; index_member < num_members; index_member++) { json_reader_read_element (reader, index_member); build_table_from_json_reader (L, reader); json_reader_end_element (reader); } } else if (json_reader_is_array (reader)) { guint index_element = 0; guint num_elements = json_reader_count_elements (reader); lua_createtable (L, num_elements, 0); for (index_element = 0; index_element < num_elements; index_element++) { json_reader_read_element (reader, index_element); lua_pushinteger (L, index_element + 1); build_table_from_json_reader (L, reader); json_reader_end_element (reader); } } else if (json_reader_is_value (reader)) { if (json_reader_get_null_value (reader)) { lua_pushnil (L); } else { /* value of the element */ JsonNode *value = json_reader_get_value (reader); switch (json_node_get_value_type (value)) { case G_TYPE_STRING: lua_pushstring (L, json_reader_get_string_value (reader)); break; case G_TYPE_INT64: lua_pushinteger (L, json_reader_get_int_value (reader)); break; case G_TYPE_DOUBLE: lua_pushnumber (L, json_reader_get_double_value (reader)); break; case G_TYPE_BOOLEAN: lua_pushnumber (L, json_reader_get_boolean_value (reader)); break; default: GRL_DEBUG ("'%d' (json-node-type) is not being handled", (gint) json_node_get_value_type (value)); lua_pushnil (L); } } } if (lua_gettop (L) > 3) { /* save this key/value on previous table */ lua_settable (L, -3); } }
GList *dt_noiseprofile_get_matching(const dt_image_t *cimg) { JsonParser *parser = darktable.noiseprofile_parser; JsonReader *reader = NULL; GList *result = NULL; if(!parser) goto end; dt_print(DT_DEBUG_CONTROL, "[noiseprofile] looking for maker `%s', model `%s'\n", cimg->camera_maker, cimg->camera_model); JsonNode *root = json_parser_get_root(parser); reader = json_reader_new(root); json_reader_read_member(reader, "noiseprofiles"); // go through all makers const int n_makers = json_reader_count_elements(reader); dt_print(DT_DEBUG_CONTROL, "[noiseprofile] found %d makers\n", n_makers); for(int i = 0; i < n_makers; i++) { json_reader_read_element(reader, i); json_reader_read_member(reader, "maker"); if(g_strstr_len(cimg->camera_maker, -1, json_reader_get_string_value(reader))) { dt_print(DT_DEBUG_CONTROL, "[noiseprofile] found `%s' as `%s'\n", cimg->camera_maker, json_reader_get_string_value(reader)); // go through all models and check those json_reader_end_member(reader); json_reader_read_member(reader, "models"); const int n_models = json_reader_count_elements(reader); dt_print(DT_DEBUG_CONTROL, "[noiseprofile] found %d models\n", n_models); for(int j = 0; j < n_models; j++) { json_reader_read_element(reader, j); json_reader_read_member(reader, "model"); if(!g_strcmp0(cimg->camera_model, json_reader_get_string_value(reader))) { dt_print(DT_DEBUG_CONTROL, "[noiseprofile] found %s\n", cimg->camera_model); // we got a match, return at most bufsize elements json_reader_end_member(reader); json_reader_read_member(reader, "profiles"); const int n_profiles = json_reader_count_elements(reader); dt_print(DT_DEBUG_CONTROL, "[noiseprofile] found %d profiles\n", n_profiles); for(int k = 0; k < n_profiles; k++) { dt_noiseprofile_t tmp_profile = { 0 }; json_reader_read_element(reader, k); gchar** member_names = json_reader_list_members(reader); // do we want to skip this entry? if(is_member(member_names, "skip")) { json_reader_read_member(reader, "skip"); gboolean skip = json_reader_get_boolean_value(reader); json_reader_end_member(reader); if(skip) { json_reader_end_element(reader); g_strfreev(member_names); continue; } } // maker tmp_profile.maker = g_strdup(cimg->camera_maker); // model tmp_profile.model = g_strdup(cimg->camera_model); // name json_reader_read_member(reader, "name"); tmp_profile.name = g_strdup(json_reader_get_string_value(reader)); json_reader_end_member(reader); // iso json_reader_read_member(reader, "iso"); tmp_profile.iso = json_reader_get_double_value(reader); json_reader_end_member(reader); // a json_reader_read_member(reader, "a"); for(int a = 0; a < 3; a++) { json_reader_read_element(reader, a); tmp_profile.a[a] = json_reader_get_double_value(reader); json_reader_end_element(reader); } json_reader_end_member(reader); // b json_reader_read_member(reader, "b"); for(int b = 0; b < 3; b++) { json_reader_read_element(reader, b); tmp_profile.b[b] = json_reader_get_double_value(reader); json_reader_end_element(reader); } json_reader_end_member(reader); json_reader_end_element(reader); // everything worked out, add tmp_profile to result dt_noiseprofile_t *new_profile = (dt_noiseprofile_t *)malloc(sizeof(dt_noiseprofile_t)); *new_profile = tmp_profile; result = g_list_append(result, new_profile); g_strfreev(member_names); } // profiles goto end; } json_reader_end_member(reader); json_reader_end_element(reader); } // models } json_reader_end_member(reader); json_reader_end_element(reader); } // makers json_reader_end_member(reader); end: if(reader) g_object_unref(reader); if(result) result = g_list_sort(result, _sort_by_iso); return result; }