1 /* vim: set ts=8 sw=8 noexpandtab: */
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 */
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 #define PRECACHE_OUTPUT_SIZE 8192
17 #define PRECACHE_OUTPUT_MAX (PRECACHE_OUTPUT_SIZE-1)
18 uint8_t data
[PRECACHE_OUTPUT_SIZE
];
22 #define ALIGN __declspec(align(16))
24 #define ALIGN __attribute__(( aligned (16) ))
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
;
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
;
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
;
46 float *input_gamma_table_gray
;
54 uint16_t *output_gamma_lut_r
;
55 uint16_t *output_gamma_lut_g
;
56 uint16_t *output_gamma_lut_b
;
58 uint16_t *output_gamma_lut_gray
;
60 size_t output_gamma_lut_r_length
;
61 size_t output_gamma_lut_g_length
;
62 size_t output_gamma_lut_b_length
;
64 size_t output_gamma_lut_gray_length
;
66 struct precache_output
*output_table_r
;
67 struct precache_output
*output_table_g
;
68 struct precache_output
*output_table_b
;
70 void (*transform_fn
)(struct _qcms_transform
*transform
, unsigned char *src
, unsigned char *dest
, size_t length
);
78 struct qcms_modular_transform
;
80 typedef void (*transform_module_fn_t
)(struct qcms_modular_transform
*transform
, float *src
, float *dest
, size_t length
);
82 struct qcms_modular_transform
{
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
;
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
;
99 uint16_t *output_gamma_lut_r
;
100 uint16_t *output_gamma_lut_g
;
101 uint16_t *output_gamma_lut_b
;
103 size_t output_gamma_lut_r_length
;
104 size_t output_gamma_lut_g_length
;
105 size_t output_gamma_lut_b_length
;
107 transform_module_fn_t transform_module_fn
;
108 struct qcms_modular_transform
*next_transform
;
111 typedef int32_t s15Fixed16Number
;
112 typedef uint16_t uInt16Number
;
113 typedef uint8_t uInt8Number
;
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];
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
;
147 // reversed elements (for mBA)
151 struct curveType
*a_curves
[10];
152 struct curveType
*b_curves
[10];
153 struct curveType
*m_curves
[10];
154 float clut_table_data
[];
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
;
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
;
173 uint16_t num_input_table_entries
;
174 uint16_t num_output_table_entries
;
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.
198 }; // I guess we need to pack this?
201 #define RGB_SIGNATURE 0x52474220
202 #define GRAY_SIGNATURE 0x47524159
203 #define XYZ_SIGNATURE 0x58595A20
204 #define LAB_SIGNATURE 0x4C616220
206 struct _qcms_profile
{
208 uint32_t color_space
;
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
;
224 struct precache_output
*output_table_r
;
225 struct precache_output
*output_table_g
;
226 struct precache_output
*output_table_b
;
230 #define inline _inline
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
)
237 return ((int32_t)a
)/65536.f
;
240 static inline s15Fixed16Number
double_to_s15Fixed16Number(double v
)
242 return (int32_t)(v
*65536);
245 static inline float uInt8Number_to_float(uInt8Number a
)
247 return ((int32_t)a
)/255.f
;
250 static inline float uInt16Number_to_float(uInt16Number a
)
252 return ((int32_t)a
)/65535.f
;
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
);
260 void qcms_transform_data_rgb_out_lut_sse2(qcms_transform
*transform
,
264 void qcms_transform_data_rgba_out_lut_sse2(qcms_transform
*transform
,
268 void qcms_transform_data_rgb_out_lut_sse1(qcms_transform
*transform
,
272 void qcms_transform_data_rgba_out_lut_sse1(qcms_transform
*transform
,
277 void qcms_transform_data_rgb_out_lut_altivec(qcms_transform
*transform
,
281 void qcms_transform_data_rgba_out_lut_altivec(qcms_transform
*transform
,
286 extern qcms_bool qcms_supports_iccv4
;
290 long __cdecl
_InterlockedIncrement(long volatile *);
291 long __cdecl
_InterlockedDecrement(long volatile *);
292 #pragma intrinsic(_InterlockedIncrement)
293 #pragma intrinsic(_InterlockedDecrement)
295 #define qcms_atomic_increment(x) _InterlockedIncrement((long volatile *)&x)
296 #define qcms_atomic_decrement(x) _InterlockedDecrement((long volatile*)&x)
300 #define qcms_atomic_increment(x) __sync_add_and_fetch(&x, 1)
301 #define qcms_atomic_decrement(x) __sync_sub_and_fetch(&x, 1)
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
315 # define OUTPUT_A_INDEX 0
316 # define OUTPUT_R_INDEX 1
317 # define OUTPUT_G_INDEX 2
318 # define OUTPUT_B_INDEX 3
321 # define RGB_OUTPUT_COMPONENTS 3
322 # define RGBA_OUTPUT_COMPONENTS 4
323 # define OUTPUT_R_INDEX 0
324 # define OUTPUT_G_INDEX 1
325 # define OUTPUT_B_INDEX 2
326 # define OUTPUT_A_INDEX 3