| OLD | NEW |
| 1 // qcms | 1 // qcms |
| 2 // Copyright (C) 2009 Mozilla Foundation | 2 // Copyright (C) 2009 Mozilla Foundation |
| 3 // | 3 // |
| 4 // Permission is hereby granted, free of charge, to any person obtaining | 4 // Permission is hereby granted, free of charge, to any person obtaining |
| 5 // a copy of this software and associated documentation files (the "Software"), | 5 // a copy of this software and associated documentation files (the "Software"), |
| 6 // to deal in the Software without restriction, including without limitation | 6 // to deal in the Software without restriction, including without limitation |
| 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, | 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 8 // and/or sell copies of the Software, and to permit persons to whom the Softwar
e | 8 // and/or sell copies of the Software, and to permit persons to whom the Softwar
e |
| 9 // is furnished to do so, subject to the following conditions: | 9 // is furnished to do so, subject to the following conditions: |
| 10 // | 10 // |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 #include "matrix.h" | 29 #include "matrix.h" |
| 30 | 30 |
| 31 #if !defined(INFINITY) | 31 #if !defined(INFINITY) |
| 32 #define INFINITY HUGE_VAL | 32 #define INFINITY HUGE_VAL |
| 33 #endif | 33 #endif |
| 34 | 34 |
| 35 #define PARAMETRIC_CURVE_TYPE 0x70617261 //'para' | 35 #define PARAMETRIC_CURVE_TYPE 0x70617261 //'para' |
| 36 | 36 |
| 37 /* value must be a value between 0 and 1 */ | 37 /* value must be a value between 0 and 1 */ |
| 38 //XXX: is the above a good restriction to have? | 38 //XXX: is the above a good restriction to have? |
| 39 float lut_interp_linear(double value, uint16_t *table, int length) | 39 float lut_interp_linear(double value, uint16_t *table, size_t length) |
| 40 { | 40 { |
| 41 int upper, lower; | 41 int upper, lower; |
| 42 value = value * (length - 1); // scale to length of the array | 42 value = value * (length - 1); // scale to length of the array |
| 43 upper = ceil(value); | 43 upper = ceil(value); |
| 44 lower = floor(value); | 44 lower = floor(value); |
| 45 //XXX: can we be more performant here? | 45 //XXX: can we be more performant here? |
| 46 value = table[upper]*(1. - (upper - value)) + table[lower]*(upper - valu
e); | 46 value = table[upper]*(1. - (upper - value)) + table[lower]*(upper - valu
e); |
| 47 /* scale the value */ | 47 /* scale the value */ |
| 48 return value * (1./65535.); | 48 return value * (1./65535.); |
| 49 } | 49 } |
| 50 | 50 |
| 51 /* same as above but takes and returns a uint16_t value representing a range fro
m 0..1 */ | 51 /* same as above but takes and returns a uint16_t value representing a range fro
m 0..1 */ |
| 52 uint16_t lut_interp_linear16(uint16_t input_value, uint16_t *table, int length) | 52 uint16_t lut_interp_linear16(uint16_t input_value, uint16_t *table, size_t lengt
h) |
| 53 { | 53 { |
| 54 /* Start scaling input_value to the length of the array: 65535*(length-1
). | 54 /* Start scaling input_value to the length of the array: 65535*(length-1
). |
| 55 * We'll divide out the 65535 next */ | 55 * We'll divide out the 65535 next */ |
| 56 » uint32_t value = (input_value * (length - 1)); | 56 » uintptr_t value = (input_value * (length - 1)); |
| 57 uint32_t upper = (value + 65534) / 65535; /* equivalent to ceil(value/65
535) */ | 57 uint32_t upper = (value + 65534) / 65535; /* equivalent to ceil(value/65
535) */ |
| 58 uint32_t lower = value / 65535; /* equivalent to floor(value/6
5535) */ | 58 uint32_t lower = value / 65535; /* equivalent to floor(value/6
5535) */ |
| 59 /* interp is the distance from upper to value scaled to 0..65535 */ | 59 /* interp is the distance from upper to value scaled to 0..65535 */ |
| 60 uint32_t interp = value % 65535; | 60 uint32_t interp = value % 65535; |
| 61 | 61 |
| 62 value = (table[upper]*(interp) + table[lower]*(65535 - interp))/65535; /
/ 0..65535*65535 | 62 value = (table[upper]*(interp) + table[lower]*(65535 - interp))/65535; /
/ 0..65535*65535 |
| 63 | 63 |
| 64 return value; | 64 return value; |
| 65 } | 65 } |
| 66 | 66 |
| 67 /* same as above but takes an input_value from 0..PRECACHE_OUTPUT_MAX | 67 /* same as above but takes an input_value from 0..PRECACHE_OUTPUT_MAX |
| 68 * and returns a uint8_t value representing a range from 0..1 */ | 68 * and returns a uint8_t value representing a range from 0..1 */ |
| 69 static | 69 static |
| 70 uint8_t lut_interp_linear_precache_output(uint32_t input_value, uint16_t *table,
int length) | 70 uint8_t lut_interp_linear_precache_output(uint32_t input_value, uint16_t *table,
size_t length) |
| 71 { | 71 { |
| 72 /* Start scaling input_value to the length of the array: PRECACHE_OUTPUT
_MAX*(length-1). | 72 /* Start scaling input_value to the length of the array: PRECACHE_OUTPUT
_MAX*(length-1). |
| 73 * We'll divide out the PRECACHE_OUTPUT_MAX next */ | 73 * We'll divide out the PRECACHE_OUTPUT_MAX next */ |
| 74 » uint32_t value = (input_value * (length - 1)); | 74 » uintptr_t value = (input_value * (length - 1)); |
| 75 | 75 |
| 76 /* equivalent to ceil(value/PRECACHE_OUTPUT_MAX) */ | 76 /* equivalent to ceil(value/PRECACHE_OUTPUT_MAX) */ |
| 77 uint32_t upper = (value + PRECACHE_OUTPUT_MAX-1) / PRECACHE_OUTPUT_MAX; | 77 uint32_t upper = (value + PRECACHE_OUTPUT_MAX-1) / PRECACHE_OUTPUT_MAX; |
| 78 /* equivalent to floor(value/PRECACHE_OUTPUT_MAX) */ | 78 /* equivalent to floor(value/PRECACHE_OUTPUT_MAX) */ |
| 79 uint32_t lower = value / PRECACHE_OUTPUT_MAX; | 79 uint32_t lower = value / PRECACHE_OUTPUT_MAX; |
| 80 /* interp is the distance from upper to value scaled to 0..PRECACHE_OUTP
UT_MAX */ | 80 /* interp is the distance from upper to value scaled to 0..PRECACHE_OUTP
UT_MAX */ |
| 81 uint32_t interp = value % PRECACHE_OUTPUT_MAX; | 81 uint32_t interp = value % PRECACHE_OUTPUT_MAX; |
| 82 | 82 |
| 83 /* the table values range from 0..65535 */ | 83 /* the table values range from 0..65535 */ |
| 84 value = (table[upper]*(interp) + table[lower]*(PRECACHE_OUTPUT_MAX - int
erp)); // 0..(65535*PRECACHE_OUTPUT_MAX) | 84 value = (table[upper]*(interp) + table[lower]*(PRECACHE_OUTPUT_MAX - int
erp)); // 0..(65535*PRECACHE_OUTPUT_MAX) |
| 85 | 85 |
| 86 /* round and scale */ | 86 /* round and scale */ |
| 87 value += (PRECACHE_OUTPUT_MAX*65535/255)/2; | 87 value += (PRECACHE_OUTPUT_MAX*65535/255)/2; |
| 88 value /= (PRECACHE_OUTPUT_MAX*65535/255); // scale to 0..255 | 88 value /= (PRECACHE_OUTPUT_MAX*65535/255); // scale to 0..255 |
| 89 return value; | 89 return value; |
| 90 } | 90 } |
| 91 | 91 |
| 92 /* value must be a value between 0 and 1 */ | 92 /* value must be a value between 0 and 1 */ |
| 93 //XXX: is the above a good restriction to have? | 93 //XXX: is the above a good restriction to have? |
| 94 float lut_interp_linear_float(float value, float *table, int length) | 94 float lut_interp_linear_float(float value, float *table, size_t length) |
| 95 { | 95 { |
| 96 int upper, lower; | 96 int upper, lower; |
| 97 value = value * (length - 1); | 97 value = value * (length - 1); |
| 98 upper = ceil(value); | 98 upper = ceil(value); |
| 99 lower = floor(value); | 99 lower = floor(value); |
| 100 //XXX: can we be more performant here? | 100 //XXX: can we be more performant here? |
| 101 value = table[upper]*(1. - (upper - value)) + table[lower]*(upper - valu
e); | 101 value = table[upper]*(1. - (upper - value)) + table[lower]*(upper - valu
e); |
| 102 /* scale the value */ | 102 /* scale the value */ |
| 103 return value; | 103 return value; |
| 104 } | 104 } |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 especially true of lookup tables that have a small number of entries. | 401 especially true of lookup tables that have a small number of entries. |
| 402 | 402 |
| 403 For example: | 403 For example: |
| 404 Using a table like: | 404 Using a table like: |
| 405 {0, 3104, 14263, 34802, 65535} | 405 {0, 3104, 14263, 34802, 65535} |
| 406 invert_lut will produce an inverse of: | 406 invert_lut will produce an inverse of: |
| 407 {3, 34459, 47529, 56801, 65535} | 407 {3, 34459, 47529, 56801, 65535} |
| 408 which has an maximum error of about 9855 (pixel difference of ~38.346) | 408 which has an maximum error of about 9855 (pixel difference of ~38.346) |
| 409 | 409 |
| 410 For now, we punt the decision of output size to the caller. */ | 410 For now, we punt the decision of output size to the caller. */ |
| 411 static uint16_t *invert_lut(uint16_t *table, int length, int out_length) | 411 static uint16_t *invert_lut(uint16_t *table, int length, size_t out_length) |
| 412 { | 412 { |
| 413 int i; | 413 int i; |
| 414 /* for now we invert the lut by creating a lut of size out_length | 414 /* for now we invert the lut by creating a lut of size out_length |
| 415 * and attempting to lookup a value for each entry using lut_inverse_int
erp16 */ | 415 * and attempting to lookup a value for each entry using lut_inverse_int
erp16 */ |
| 416 uint16_t *output = malloc(sizeof(uint16_t)*out_length); | 416 uint16_t *output = malloc(sizeof(uint16_t)*out_length); |
| 417 if (!output) | 417 if (!output) |
| 418 return NULL; | 418 return NULL; |
| 419 | 419 |
| 420 for (i = 0; i < out_length; i++) { | 420 for (i = 0; i < out_length; i++) { |
| 421 double x = ((double) i * 65535.) / (double) (out_length - 1); | 421 double x = ((double) i * 65535.) / (double) (out_length - 1); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 // measurement or data, however it is what lcms uses
. | 568 // measurement or data, however it is what lcms uses
. |
| 569 *output_gamma_lut_length = trc->count; | 569 *output_gamma_lut_length = trc->count; |
| 570 if (*output_gamma_lut_length < 256) | 570 if (*output_gamma_lut_length < 256) |
| 571 *output_gamma_lut_length = 256; | 571 *output_gamma_lut_length = 256; |
| 572 | 572 |
| 573 *output_gamma_lut = invert_lut(trc->data, trc->count, *o
utput_gamma_lut_length); | 573 *output_gamma_lut = invert_lut(trc->data, trc->count, *o
utput_gamma_lut_length); |
| 574 } | 574 } |
| 575 } | 575 } |
| 576 | 576 |
| 577 } | 577 } |
| OLD | NEW |