void compute_curve_gamma_table_type1(float gamma_table[256], uint16_t gamma) { unsigned int i; float gamma_float = u8Fixed8Number_to_float(gamma); for (i = 0; i < 256; i++) { // 0..1^(0..255 + 255/256) will always be between 0 and 1 gamma_table[i] = pow(i/255., gamma_float); } }
qcms_bool compute_precache(struct curveType *trc, uint8_t *output) { if (trc->type == PARAMETRIC_CURVE_TYPE) { float gamma_table[256]; uint16_t gamma_table_uint[256]; uint16_t i; uint16_t *inverted; int inverted_size = 256; compute_curve_gamma_table_type_parametric(gamma_table, trc->parameter, trc->count); for(i = 0; i < 256; i++) { gamma_table_uint[i] = (uint16_t)(gamma_table[i] * 65535); } //XXX: the choice of a minimum of 256 here is not backed by any theory, // measurement or data, howeve r it is what lcms uses. // the maximum number we would need is 65535 because that's the // accuracy used for computing the pre cache table if (inverted_size < 256) inverted_size = 256; inverted = invert_lut(gamma_table_uint, 256, inverted_size); if (!inverted) return false; compute_precache_lut(output, inverted, inverted_size); free(inverted); } else { if (trc->count == 0) { compute_precache_linear(output); } else if (trc->count == 1) { compute_precache_pow(output, 1./u8Fixed8Number_to_float(trc->data[0])); } else { uint16_t *inverted; int inverted_size = trc->count; //XXX: the choice of a minimum of 256 here is not backed by any theory, // measurement or data, howeve r it is what lcms uses. // the maximum number we would need is 65535 because that's the // accuracy used for computing the pre cache table if (inverted_size < 256) inverted_size = 256; inverted = invert_lut(trc->data, trc->count, inverted_size); if (!inverted) return false; compute_precache_lut(output, inverted, inverted_size); free(inverted); } } return true; }
void build_output_lut(struct curveType *trc, uint16_t **output_gamma_lut, size_t *output_gamma_lut_length) { if (trc->type == PARAMETRIC_CURVE_TYPE) { float gamma_table[256]; uint16_t i; uint16_t *output = malloc(sizeof(uint16_t)*256); if (!output) { *output_gamma_lut = NULL; return; } compute_curve_gamma_table_type_parametric(gamma_table, trc->parameter, trc->count); *output_gamma_lut_length = 256; for(i = 0; i < 256; i++) { output[i] = (uint16_t)(gamma_table[i] * 65535); } *output_gamma_lut = output; } else { if (trc->count == 0) { *output_gamma_lut = build_linear_table(4096); *output_gamma_lut_length = 4096; } else if (trc->count == 1) { float gamma = 1./u8Fixed8Number_to_float(trc->data[0]); *output_gamma_lut = build_pow_table(gamma, 4096); *output_gamma_lut_length = 4096; } else { //XXX: the choice of a minimum of 256 here is not backed by any theory, // measurement or data, however it is what lcms uses. *output_gamma_lut_length = trc->count; if (*output_gamma_lut_length < 256) *output_gamma_lut_length = 256; *output_gamma_lut = invert_lut(trc->data, trc->count, *output_gamma_lut_length); } } }
float *build_input_gamma_table(struct curveType *TRC) { float *gamma_table; if (!TRC) return NULL; gamma_table = malloc(sizeof(float)*256); if (gamma_table) { if (TRC->type == PARAMETRIC_CURVE_TYPE) { compute_curve_gamma_table_type_parametric(gamma_table, TRC->parameter, TRC->count); } else { if (TRC->count == 0) { compute_curve_gamma_table_type0(gamma_table); } else if (TRC->count == 1) { compute_curve_gamma_table_type1(gamma_table, u8Fixed8Number_to_float(TRC->data[0])); } else { compute_curve_gamma_table_type2(gamma_table, TRC->data, TRC->count); } } } validate_gamma_table(gamma_table); return gamma_table; }