OLD | NEW |
| (Empty) |
1 /* vim: set ts=8 sw=8 noexpandtab: */ | |
2 // qcms | |
3 // Copyright (C) 2009 Mozilla Foundation | |
4 // | |
5 // Permission is hereby granted, free of charge, to any person obtaining | |
6 // a copy of this software and associated documentation files (the "Software"), | |
7 // to deal in the Software without restriction, including without limitation | |
8 // the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
9 // and/or sell copies of the Software, and to permit persons to whom the Softwar
e | |
10 // is furnished to do so, subject to the following conditions: | |
11 // | |
12 // The above copyright notice and this permission notice shall be included in | |
13 // all copies or substantial portions of the Software. | |
14 // | |
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO | |
17 // THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
22 | |
23 #include "qcms.h" | |
24 #include "qcmstypes.h" | |
25 | |
26 /* used as a lookup table for the output transformation. | |
27 * we refcount them so we only need to have one around per output | |
28 * profile, instead of duplicating them per transform */ | |
29 struct precache_output | |
30 { | |
31 int ref_count; | |
32 /* We previously used a count of 65536 here but that seems like more | |
33 * precision than we actually need. By reducing the size we can | |
34 * improve startup performance and reduce memory usage. ColorSync on | |
35 * 10.5 uses 4097 which is perhaps because they use a fixed point | |
36 * representation where 1. is represented by 0x1000. */ | |
37 #define PRECACHE_OUTPUT_SIZE 8192 | |
38 #define PRECACHE_OUTPUT_MAX (PRECACHE_OUTPUT_SIZE-1) | |
39 uint8_t data[PRECACHE_OUTPUT_SIZE]; | |
40 }; | |
41 | |
42 #ifdef _MSC_VER | |
43 #define ALIGN __declspec(align(16)) | |
44 #else | |
45 #define ALIGN __attribute__(( aligned (16) )) | |
46 #endif | |
47 | |
48 struct _qcms_transform { | |
49 float ALIGN matrix[3][4]; | |
50 float *input_gamma_table_r; | |
51 float *input_gamma_table_g; | |
52 float *input_gamma_table_b; | |
53 | |
54 float *input_clut_table_r; | |
55 float *input_clut_table_g; | |
56 float *input_clut_table_b; | |
57 uint16_t input_clut_table_length; | |
58 float *r_clut; | |
59 float *g_clut; | |
60 float *b_clut; | |
61 uint16_t grid_size; | |
62 float *output_clut_table_r; | |
63 float *output_clut_table_g; | |
64 float *output_clut_table_b; | |
65 uint16_t output_clut_table_length; | |
66 | |
67 float *input_gamma_table_gray; | |
68 | |
69 float out_gamma_r; | |
70 float out_gamma_g; | |
71 float out_gamma_b; | |
72 | |
73 float out_gamma_gray; | |
74 | |
75 uint16_t *output_gamma_lut_r; | |
76 uint16_t *output_gamma_lut_g; | |
77 uint16_t *output_gamma_lut_b; | |
78 | |
79 uint16_t *output_gamma_lut_gray; | |
80 | |
81 size_t output_gamma_lut_r_length; | |
82 size_t output_gamma_lut_g_length; | |
83 size_t output_gamma_lut_b_length; | |
84 | |
85 size_t output_gamma_lut_gray_length; | |
86 | |
87 struct precache_output *output_table_r; | |
88 struct precache_output *output_table_g; | |
89 struct precache_output *output_table_b; | |
90 | |
91 void (*transform_fn)(struct _qcms_transform *transform, unsigned char *s
rc, unsigned char *dest, size_t length); | |
92 }; | |
93 | |
94 struct matrix { | |
95 float m[3][3]; | |
96 bool invalid; | |
97 }; | |
98 | |
99 struct qcms_modular_transform; | |
100 | |
101 typedef void (*transform_module_fn_t)(struct qcms_modular_transform *transform,
float *src, float *dest, size_t length); | |
102 | |
103 struct qcms_modular_transform { | |
104 struct matrix matrix; | |
105 float tx, ty, tz; | |
106 | |
107 float *input_clut_table_r; | |
108 float *input_clut_table_g; | |
109 float *input_clut_table_b; | |
110 uint16_t input_clut_table_length; | |
111 float *r_clut; | |
112 float *g_clut; | |
113 float *b_clut; | |
114 uint16_t grid_size; | |
115 float *output_clut_table_r; | |
116 float *output_clut_table_g; | |
117 float *output_clut_table_b; | |
118 uint16_t output_clut_table_length; | |
119 | |
120 uint16_t *output_gamma_lut_r; | |
121 uint16_t *output_gamma_lut_g; | |
122 uint16_t *output_gamma_lut_b; | |
123 | |
124 size_t output_gamma_lut_r_length; | |
125 size_t output_gamma_lut_g_length; | |
126 size_t output_gamma_lut_b_length; | |
127 | |
128 transform_module_fn_t transform_module_fn; | |
129 struct qcms_modular_transform *next_transform; | |
130 }; | |
131 | |
132 typedef int32_t s15Fixed16Number; | |
133 typedef uint16_t uInt16Number; | |
134 typedef uint8_t uInt8Number; | |
135 | |
136 struct XYZNumber { | |
137 s15Fixed16Number X; | |
138 s15Fixed16Number Y; | |
139 s15Fixed16Number Z; | |
140 }; | |
141 | |
142 struct curveType { | |
143 uint32_t type; | |
144 uint32_t count; | |
145 float parameter[7]; | |
146 uInt16Number data[]; | |
147 }; | |
148 | |
149 struct lutmABType { | |
150 uint8_t num_in_channels; | |
151 uint8_t num_out_channels; | |
152 // 16 is the upperbound, actual is 0..num_in_channels. | |
153 uint8_t num_grid_points[16]; | |
154 | |
155 s15Fixed16Number e00; | |
156 s15Fixed16Number e01; | |
157 s15Fixed16Number e02; | |
158 s15Fixed16Number e03; | |
159 s15Fixed16Number e10; | |
160 s15Fixed16Number e11; | |
161 s15Fixed16Number e12; | |
162 s15Fixed16Number e13; | |
163 s15Fixed16Number e20; | |
164 s15Fixed16Number e21; | |
165 s15Fixed16Number e22; | |
166 s15Fixed16Number e23; | |
167 | |
168 // reversed elements (for mBA) | |
169 bool reversed; | |
170 | |
171 float *clut_table; | |
172 struct curveType *a_curves[10]; | |
173 struct curveType *b_curves[10]; | |
174 struct curveType *m_curves[10]; | |
175 float clut_table_data[]; | |
176 }; | |
177 | |
178 /* should lut8Type and lut16Type be different types? */ | |
179 struct lutType { // used by lut8Type/lut16Type (mft2) only | |
180 uint8_t num_input_channels; | |
181 uint8_t num_output_channels; | |
182 uint8_t num_clut_grid_points; | |
183 | |
184 s15Fixed16Number e00; | |
185 s15Fixed16Number e01; | |
186 s15Fixed16Number e02; | |
187 s15Fixed16Number e10; | |
188 s15Fixed16Number e11; | |
189 s15Fixed16Number e12; | |
190 s15Fixed16Number e20; | |
191 s15Fixed16Number e21; | |
192 s15Fixed16Number e22; | |
193 | |
194 uint16_t num_input_table_entries; | |
195 uint16_t num_output_table_entries; | |
196 | |
197 float *input_table; | |
198 float *clut_table; | |
199 float *output_table; | |
200 | |
201 float table_data[]; | |
202 }; | |
203 #if 0 | |
204 /* this is from an intial idea of having the struct correspond to the data in | |
205 * the file. I decided that it wasn't a good idea. | |
206 */ | |
207 struct tag_value { | |
208 uint32_t type; | |
209 union { | |
210 struct { | |
211 uint32_t reserved; | |
212 struct { | |
213 s15Fixed16Number X; | |
214 s15Fixed16Number Y; | |
215 s15Fixed16Number Z; | |
216 } XYZNumber; | |
217 } XYZType; | |
218 }; | |
219 }; // I guess we need to pack this? | |
220 #endif | |
221 | |
222 #define RGB_SIGNATURE 0x52474220 | |
223 #define GRAY_SIGNATURE 0x47524159 | |
224 #define XYZ_SIGNATURE 0x58595A20 | |
225 #define LAB_SIGNATURE 0x4C616220 | |
226 | |
227 struct _qcms_profile { | |
228 uint32_t class; | |
229 uint32_t color_space; | |
230 uint32_t pcs; | |
231 qcms_intent rendering_intent; | |
232 struct XYZNumber redColorant; | |
233 struct XYZNumber blueColorant; | |
234 struct XYZNumber greenColorant; | |
235 struct curveType *redTRC; | |
236 struct curveType *blueTRC; | |
237 struct curveType *greenTRC; | |
238 struct curveType *grayTRC; | |
239 struct lutType *A2B0; | |
240 struct lutType *B2A0; | |
241 struct lutmABType *mAB; | |
242 struct lutmABType *mBA; | |
243 struct matrix chromaticAdaption; | |
244 | |
245 struct precache_output *output_table_r; | |
246 struct precache_output *output_table_g; | |
247 struct precache_output *output_table_b; | |
248 }; | |
249 | |
250 #ifdef _MSC_VER | |
251 #define inline _inline | |
252 #endif | |
253 | |
254 /* produces the nearest float to 'a' with a maximum error | |
255 * of 1/1024 which happens for large values like 0x40000040 */ | |
256 static inline float s15Fixed16Number_to_float(s15Fixed16Number a) | |
257 { | |
258 return ((int32_t)a)/65536.f; | |
259 } | |
260 | |
261 static inline s15Fixed16Number double_to_s15Fixed16Number(double v) | |
262 { | |
263 return (int32_t)(v*65536); | |
264 } | |
265 | |
266 static inline float uInt8Number_to_float(uInt8Number a) | |
267 { | |
268 return ((int32_t)a)/255.f; | |
269 } | |
270 | |
271 static inline float uInt16Number_to_float(uInt16Number a) | |
272 { | |
273 return ((int32_t)a)/65535.f; | |
274 } | |
275 | |
276 | |
277 void precache_release(struct precache_output *p); | |
278 qcms_bool set_rgb_colorants(qcms_profile *profile, qcms_CIE_xyY white_point, qcm
s_CIE_xyYTRIPLE primaries); | |
279 | |
280 void qcms_transform_data_rgb_out_lut_sse2(qcms_transform *transform, | |
281 unsigned char *src, | |
282 unsigned char *dest, | |
283 size_t length); | |
284 void qcms_transform_data_rgba_out_lut_sse2(qcms_transform *transform, | |
285 unsigned char *src, | |
286 unsigned char *dest, | |
287 size_t length); | |
288 void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform, | |
289 unsigned char *src, | |
290 unsigned char *dest, | |
291 size_t length); | |
292 void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform, | |
293 unsigned char *src, | |
294 unsigned char *dest, | |
295 size_t length); | |
296 | |
297 extern qcms_bool qcms_supports_iccv4; | |
OLD | NEW |