static const char *TAG = "gamma"; #include #include #include "gamma.hpp" #include "utils.hpp" namespace Gamma { static uint8_t gamma[256]; static uint8_t inv_gamma[256]; static void default_table(uint8_t *table) { for (int val = 0; val < 256; ++val) *table++ = val; } static void json_table(cJSON *jarray, uint8_t *table) { if (jarray->type != cJSON_Array) { ESP_LOGE(TAG, "Not an array: %s", jarray->string); } int count = cJSON_GetArraySize(jarray); if (count != 256) { ESP_LOGE(TAG, "Wrong size for %s: %d", jarray->string, count); } uint8_t *ptr = table; cJSON *jnumber; cJSON_ArrayForEach(jnumber, jarray) { if (jnumber->type != cJSON_Number) { ESP_LOGE(TAG, "Not a number: %s", jnumber->string); default_table(table); return; } *ptr++ = (uint8_t)jnumber->valueint; } } static inline cJSON* load_json(const char *path) { return cJSON_Parse(read_file(path).c_str()); } void reload() { default_table(gamma); default_table(inv_gamma); cJSON *json = load_json("/spiffs/gamma.json"); if (!json) { ESP_LOGE(TAG, "No gamma values!"); return; } cJSON *jgamma = cJSON_GetObjectItem(json, "gamma"); if (!jgamma) { ESP_LOGE(TAG, "No gamma values!"); cJSON_Delete(json); return; } cJSON *jinv_gamma = cJSON_GetObjectItem(json, "inv_gamma"); if (!jinv_gamma) { ESP_LOGE(TAG, "No inverse gamma values!"); cJSON_Delete(json); return; } json_table(jgamma, gamma); json_table(jinv_gamma, inv_gamma); cJSON_Delete(json); } /* static inline uint8_t scale(int val, int num, int dem) { if (dem == 0) return 0; int val = (val * num) / dem; return (val >= 256 ? 255 : val); } */ static inline Color correct_single(Color c, int b) { return {gamma[(b * c.r) / 255], gamma[(b * c.g) / 255], gamma[(b * c.b) / 255]}; } void correct(Color *dst, const Color *src, int n, int b) { while(n-- > 0) *dst++ = correct_single(*src++, b); } Color wrong_single(Color c) { return {inv_gamma[c.r], inv_gamma[c.g], inv_gamma[c.b]}; } } // Gamma