/src/mozilla-central/gfx/qcms/qcmsint.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* vim: set ts=8 sw=8 noexpandtab: */ |
2 | | #include "qcms.h" |
3 | | #include "qcmstypes.h" |
4 | | |
5 | | /* used as a lookup table for the output transformation. |
6 | | * we refcount them so we only need to have one around per output |
7 | | * profile, instead of duplicating them per transform */ |
8 | | struct precache_output |
9 | | { |
10 | | int ref_count; |
11 | | /* We previously used a count of 65536 here but that seems like more |
12 | | * precision than we actually need. By reducing the size we can |
13 | | * improve startup performance and reduce memory usage. ColorSync on |
14 | | * 10.5 uses 4097 which is perhaps because they use a fixed point |
15 | | * representation where 1. is represented by 0x1000. */ |
16 | 0 | #define PRECACHE_OUTPUT_SIZE 8192 |
17 | 0 | #define PRECACHE_OUTPUT_MAX (PRECACHE_OUTPUT_SIZE-1) |
18 | | uint8_t data[PRECACHE_OUTPUT_SIZE]; |
19 | | }; |
20 | | |
21 | | #ifdef _MSC_VER |
22 | | #define ALIGN __declspec(align(16)) |
23 | | #else |
24 | | #define ALIGN __attribute__(( aligned (16) )) |
25 | | #endif |
26 | | |
27 | | struct _qcms_transform { |
28 | | float ALIGN matrix[3][4]; |
29 | | float *input_gamma_table_r; |
30 | | float *input_gamma_table_g; |
31 | | float *input_gamma_table_b; |
32 | | |
33 | | float *input_clut_table_r; |
34 | | float *input_clut_table_g; |
35 | | float *input_clut_table_b; |
36 | | uint16_t input_clut_table_length; |
37 | | float *r_clut; |
38 | | float *g_clut; |
39 | | float *b_clut; |
40 | | uint16_t grid_size; |
41 | | float *output_clut_table_r; |
42 | | float *output_clut_table_g; |
43 | | float *output_clut_table_b; |
44 | | uint16_t output_clut_table_length; |
45 | | |
46 | | float *input_gamma_table_gray; |
47 | | |
48 | | float out_gamma_r; |
49 | | float out_gamma_g; |
50 | | float out_gamma_b; |
51 | | |
52 | | float out_gamma_gray; |
53 | | |
54 | | uint16_t *output_gamma_lut_r; |
55 | | uint16_t *output_gamma_lut_g; |
56 | | uint16_t *output_gamma_lut_b; |
57 | | |
58 | | uint16_t *output_gamma_lut_gray; |
59 | | |
60 | | size_t output_gamma_lut_r_length; |
61 | | size_t output_gamma_lut_g_length; |
62 | | size_t output_gamma_lut_b_length; |
63 | | |
64 | | size_t output_gamma_lut_gray_length; |
65 | | |
66 | | struct precache_output *output_table_r; |
67 | | struct precache_output *output_table_g; |
68 | | struct precache_output *output_table_b; |
69 | | |
70 | | void (*transform_fn)(struct _qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length); |
71 | | }; |
72 | | |
73 | | struct matrix { |
74 | | float m[3][3]; |
75 | | bool invalid; |
76 | | }; |
77 | | |
78 | | struct qcms_modular_transform; |
79 | | |
80 | | typedef void (*transform_module_fn_t)(struct qcms_modular_transform *transform, float *src, float *dest, size_t length); |
81 | | |
82 | | struct qcms_modular_transform { |
83 | | struct matrix matrix; |
84 | | float tx, ty, tz; |
85 | | |
86 | | float *input_clut_table_r; |
87 | | float *input_clut_table_g; |
88 | | float *input_clut_table_b; |
89 | | uint16_t input_clut_table_length; |
90 | | float *r_clut; |
91 | | float *g_clut; |
92 | | float *b_clut; |
93 | | uint16_t grid_size; |
94 | | float *output_clut_table_r; |
95 | | float *output_clut_table_g; |
96 | | float *output_clut_table_b; |
97 | | uint16_t output_clut_table_length; |
98 | | |
99 | | uint16_t *output_gamma_lut_r; |
100 | | uint16_t *output_gamma_lut_g; |
101 | | uint16_t *output_gamma_lut_b; |
102 | | |
103 | | size_t output_gamma_lut_r_length; |
104 | | size_t output_gamma_lut_g_length; |
105 | | size_t output_gamma_lut_b_length; |
106 | | |
107 | | transform_module_fn_t transform_module_fn; |
108 | | struct qcms_modular_transform *next_transform; |
109 | | }; |
110 | | |
111 | | typedef int32_t s15Fixed16Number; |
112 | | typedef uint16_t uInt16Number; |
113 | | typedef uint8_t uInt8Number; |
114 | | |
115 | | struct XYZNumber { |
116 | | s15Fixed16Number X; |
117 | | s15Fixed16Number Y; |
118 | | s15Fixed16Number Z; |
119 | | }; |
120 | | |
121 | | struct curveType { |
122 | | uint32_t type; |
123 | | uint32_t count; |
124 | | float parameter[7]; |
125 | | uInt16Number data[]; |
126 | | }; |
127 | | |
128 | | struct lutmABType { |
129 | | uint8_t num_in_channels; |
130 | | uint8_t num_out_channels; |
131 | | // 16 is the upperbound, actual is 0..num_in_channels. |
132 | | uint8_t num_grid_points[16]; |
133 | | |
134 | | s15Fixed16Number e00; |
135 | | s15Fixed16Number e01; |
136 | | s15Fixed16Number e02; |
137 | | s15Fixed16Number e03; |
138 | | s15Fixed16Number e10; |
139 | | s15Fixed16Number e11; |
140 | | s15Fixed16Number e12; |
141 | | s15Fixed16Number e13; |
142 | | s15Fixed16Number e20; |
143 | | s15Fixed16Number e21; |
144 | | s15Fixed16Number e22; |
145 | | s15Fixed16Number e23; |
146 | | |
147 | | // reversed elements (for mBA) |
148 | | bool reversed; |
149 | | |
150 | | float *clut_table; |
151 | | struct curveType *a_curves[10]; |
152 | | struct curveType *b_curves[10]; |
153 | | struct curveType *m_curves[10]; |
154 | | float clut_table_data[]; |
155 | | }; |
156 | | |
157 | | /* should lut8Type and lut16Type be different types? */ |
158 | | struct lutType { // used by lut8Type/lut16Type (mft2) only |
159 | | uint8_t num_input_channels; |
160 | | uint8_t num_output_channels; |
161 | | uint8_t num_clut_grid_points; |
162 | | |
163 | | s15Fixed16Number e00; |
164 | | s15Fixed16Number e01; |
165 | | s15Fixed16Number e02; |
166 | | s15Fixed16Number e10; |
167 | | s15Fixed16Number e11; |
168 | | s15Fixed16Number e12; |
169 | | s15Fixed16Number e20; |
170 | | s15Fixed16Number e21; |
171 | | s15Fixed16Number e22; |
172 | | |
173 | | uint16_t num_input_table_entries; |
174 | | uint16_t num_output_table_entries; |
175 | | |
176 | | float *input_table; |
177 | | float *clut_table; |
178 | | float *output_table; |
179 | | |
180 | | float table_data[]; |
181 | | }; |
182 | | #if 0 |
183 | | /* this is from an intial idea of having the struct correspond to the data in |
184 | | * the file. I decided that it wasn't a good idea. |
185 | | */ |
186 | | struct tag_value { |
187 | | uint32_t type; |
188 | | union { |
189 | | struct { |
190 | | uint32_t reserved; |
191 | | struct { |
192 | | s15Fixed16Number X; |
193 | | s15Fixed16Number Y; |
194 | | s15Fixed16Number Z; |
195 | | } XYZNumber; |
196 | | } XYZType; |
197 | | }; |
198 | | }; // I guess we need to pack this? |
199 | | #endif |
200 | | |
201 | 0 | #define RGB_SIGNATURE 0x52474220 |
202 | 0 | #define GRAY_SIGNATURE 0x47524159 |
203 | 0 | #define XYZ_SIGNATURE 0x58595A20 |
204 | 0 | #define LAB_SIGNATURE 0x4C616220 |
205 | | |
206 | | struct _qcms_profile { |
207 | | uint32_t class; |
208 | | uint32_t color_space; |
209 | | uint32_t pcs; |
210 | | qcms_intent rendering_intent; |
211 | | struct XYZNumber redColorant; |
212 | | struct XYZNumber blueColorant; |
213 | | struct XYZNumber greenColorant; |
214 | | struct curveType *redTRC; |
215 | | struct curveType *blueTRC; |
216 | | struct curveType *greenTRC; |
217 | | struct curveType *grayTRC; |
218 | | struct lutType *A2B0; |
219 | | struct lutType *B2A0; |
220 | | struct lutmABType *mAB; |
221 | | struct lutmABType *mBA; |
222 | | struct matrix chromaticAdaption; |
223 | | |
224 | | struct precache_output *output_table_r; |
225 | | struct precache_output *output_table_g; |
226 | | struct precache_output *output_table_b; |
227 | | }; |
228 | | |
229 | | #ifdef _MSC_VER |
230 | | #define inline _inline |
231 | | #endif |
232 | | |
233 | | /* produces the nearest float to 'a' with a maximum error |
234 | | * of 1/1024 which happens for large values like 0x40000040 */ |
235 | | static inline float s15Fixed16Number_to_float(s15Fixed16Number a) |
236 | 0 | { |
237 | 0 | return ((int32_t)a)/65536.f; |
238 | 0 | } Unexecuted instantiation: chain.c:s15Fixed16Number_to_float Unexecuted instantiation: iccread.c:s15Fixed16Number_to_float Unexecuted instantiation: matrix.c:s15Fixed16Number_to_float Unexecuted instantiation: transform-sse1.c:s15Fixed16Number_to_float Unexecuted instantiation: transform-sse2.c:s15Fixed16Number_to_float Unexecuted instantiation: transform.c:s15Fixed16Number_to_float Unexecuted instantiation: transform_util.c:s15Fixed16Number_to_float |
239 | | |
240 | | static inline s15Fixed16Number double_to_s15Fixed16Number(double v) |
241 | 0 | { |
242 | 0 | return (int32_t)(v*65536); |
243 | 0 | } Unexecuted instantiation: chain.c:double_to_s15Fixed16Number Unexecuted instantiation: iccread.c:double_to_s15Fixed16Number Unexecuted instantiation: matrix.c:double_to_s15Fixed16Number Unexecuted instantiation: transform-sse1.c:double_to_s15Fixed16Number Unexecuted instantiation: transform-sse2.c:double_to_s15Fixed16Number Unexecuted instantiation: transform.c:double_to_s15Fixed16Number Unexecuted instantiation: transform_util.c:double_to_s15Fixed16Number |
244 | | |
245 | | static inline float uInt8Number_to_float(uInt8Number a) |
246 | 0 | { |
247 | 0 | return ((int32_t)a)/255.f; |
248 | 0 | } Unexecuted instantiation: chain.c:uInt8Number_to_float Unexecuted instantiation: iccread.c:uInt8Number_to_float Unexecuted instantiation: matrix.c:uInt8Number_to_float Unexecuted instantiation: transform-sse1.c:uInt8Number_to_float Unexecuted instantiation: transform-sse2.c:uInt8Number_to_float Unexecuted instantiation: transform.c:uInt8Number_to_float Unexecuted instantiation: transform_util.c:uInt8Number_to_float |
249 | | |
250 | | static inline float uInt16Number_to_float(uInt16Number a) |
251 | 0 | { |
252 | 0 | return ((int32_t)a)/65535.f; |
253 | 0 | } Unexecuted instantiation: chain.c:uInt16Number_to_float Unexecuted instantiation: iccread.c:uInt16Number_to_float Unexecuted instantiation: matrix.c:uInt16Number_to_float Unexecuted instantiation: transform-sse1.c:uInt16Number_to_float Unexecuted instantiation: transform-sse2.c:uInt16Number_to_float Unexecuted instantiation: transform.c:uInt16Number_to_float Unexecuted instantiation: transform_util.c:uInt16Number_to_float |
254 | | |
255 | | |
256 | | void precache_release(struct precache_output *p); |
257 | | qcms_bool set_rgb_colorants(qcms_profile *profile, qcms_CIE_xyY white_point, qcms_CIE_xyYTRIPLE primaries); |
258 | | qcms_bool get_rgb_colorants(struct matrix *colorants, qcms_CIE_xyY white_point, qcms_CIE_xyYTRIPLE primaries); |
259 | | |
260 | | void qcms_transform_data_rgb_out_lut_sse2(qcms_transform *transform, |
261 | | unsigned char *src, |
262 | | unsigned char *dest, |
263 | | size_t length); |
264 | | void qcms_transform_data_rgba_out_lut_sse2(qcms_transform *transform, |
265 | | unsigned char *src, |
266 | | unsigned char *dest, |
267 | | size_t length); |
268 | | void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform, |
269 | | unsigned char *src, |
270 | | unsigned char *dest, |
271 | | size_t length); |
272 | | void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform, |
273 | | unsigned char *src, |
274 | | unsigned char *dest, |
275 | | size_t length); |
276 | | |
277 | | void qcms_transform_data_rgb_out_lut_altivec(qcms_transform *transform, |
278 | | unsigned char *src, |
279 | | unsigned char *dest, |
280 | | size_t length); |
281 | | void qcms_transform_data_rgba_out_lut_altivec(qcms_transform *transform, |
282 | | unsigned char *src, |
283 | | unsigned char *dest, |
284 | | size_t length); |
285 | | |
286 | | extern qcms_bool qcms_supports_iccv4; |
287 | | |
288 | | #ifdef _MSC_VER |
289 | | |
290 | | long __cdecl _InterlockedIncrement(long volatile *); |
291 | | long __cdecl _InterlockedDecrement(long volatile *); |
292 | | #pragma intrinsic(_InterlockedIncrement) |
293 | | #pragma intrinsic(_InterlockedDecrement) |
294 | | |
295 | | #define qcms_atomic_increment(x) _InterlockedIncrement((long volatile *)&x) |
296 | | #define qcms_atomic_decrement(x) _InterlockedDecrement((long volatile*)&x) |
297 | | |
298 | | #else |
299 | | |
300 | 0 | #define qcms_atomic_increment(x) __sync_add_and_fetch(&x, 1) |
301 | 0 | #define qcms_atomic_decrement(x) __sync_sub_and_fetch(&x, 1) |
302 | | |
303 | | #endif |
304 | | |
305 | | |
306 | | #ifdef NATIVE_OUTPUT |
307 | | # define RGB_OUTPUT_COMPONENTS 4 |
308 | | # define RGBA_OUTPUT_COMPONENTS 4 |
309 | | # ifdef IS_LITTLE_ENDIAN |
310 | | # define OUTPUT_A_INDEX 3 |
311 | | # define OUTPUT_R_INDEX 2 |
312 | | # define OUTPUT_G_INDEX 1 |
313 | | # define OUTPUT_B_INDEX 0 |
314 | | # else |
315 | | # define OUTPUT_A_INDEX 0 |
316 | | # define OUTPUT_R_INDEX 1 |
317 | | # define OUTPUT_G_INDEX 2 |
318 | | # define OUTPUT_B_INDEX 3 |
319 | | # endif |
320 | | #else |
321 | 0 | # define RGB_OUTPUT_COMPONENTS 3 |
322 | 0 | # define RGBA_OUTPUT_COMPONENTS 4 |
323 | 0 | # define OUTPUT_R_INDEX 0 |
324 | 0 | # define OUTPUT_G_INDEX 1 |
325 | 0 | # define OUTPUT_B_INDEX 2 |
326 | 0 | # define OUTPUT_A_INDEX 3 |
327 | | #endif |