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 |