1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/qcms/qcmsint.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,327 @@ 1.4 +/* vim: set ts=8 sw=8 noexpandtab: */ 1.5 +#include "qcms.h" 1.6 +#include "qcmstypes.h" 1.7 + 1.8 +/* used as a lookup table for the output transformation. 1.9 + * we refcount them so we only need to have one around per output 1.10 + * profile, instead of duplicating them per transform */ 1.11 +struct precache_output 1.12 +{ 1.13 + int ref_count; 1.14 + /* We previously used a count of 65536 here but that seems like more 1.15 + * precision than we actually need. By reducing the size we can 1.16 + * improve startup performance and reduce memory usage. ColorSync on 1.17 + * 10.5 uses 4097 which is perhaps because they use a fixed point 1.18 + * representation where 1. is represented by 0x1000. */ 1.19 +#define PRECACHE_OUTPUT_SIZE 8192 1.20 +#define PRECACHE_OUTPUT_MAX (PRECACHE_OUTPUT_SIZE-1) 1.21 + uint8_t data[PRECACHE_OUTPUT_SIZE]; 1.22 +}; 1.23 + 1.24 +#ifdef _MSC_VER 1.25 +#define ALIGN __declspec(align(16)) 1.26 +#else 1.27 +#define ALIGN __attribute__(( aligned (16) )) 1.28 +#endif 1.29 + 1.30 +struct _qcms_transform { 1.31 + float ALIGN matrix[3][4]; 1.32 + float *input_gamma_table_r; 1.33 + float *input_gamma_table_g; 1.34 + float *input_gamma_table_b; 1.35 + 1.36 + float *input_clut_table_r; 1.37 + float *input_clut_table_g; 1.38 + float *input_clut_table_b; 1.39 + uint16_t input_clut_table_length; 1.40 + float *r_clut; 1.41 + float *g_clut; 1.42 + float *b_clut; 1.43 + uint16_t grid_size; 1.44 + float *output_clut_table_r; 1.45 + float *output_clut_table_g; 1.46 + float *output_clut_table_b; 1.47 + uint16_t output_clut_table_length; 1.48 + 1.49 + float *input_gamma_table_gray; 1.50 + 1.51 + float out_gamma_r; 1.52 + float out_gamma_g; 1.53 + float out_gamma_b; 1.54 + 1.55 + float out_gamma_gray; 1.56 + 1.57 + uint16_t *output_gamma_lut_r; 1.58 + uint16_t *output_gamma_lut_g; 1.59 + uint16_t *output_gamma_lut_b; 1.60 + 1.61 + uint16_t *output_gamma_lut_gray; 1.62 + 1.63 + size_t output_gamma_lut_r_length; 1.64 + size_t output_gamma_lut_g_length; 1.65 + size_t output_gamma_lut_b_length; 1.66 + 1.67 + size_t output_gamma_lut_gray_length; 1.68 + 1.69 + struct precache_output *output_table_r; 1.70 + struct precache_output *output_table_g; 1.71 + struct precache_output *output_table_b; 1.72 + 1.73 + void (*transform_fn)(struct _qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length); 1.74 +}; 1.75 + 1.76 +struct matrix { 1.77 + float m[3][3]; 1.78 + bool invalid; 1.79 +}; 1.80 + 1.81 +struct qcms_modular_transform; 1.82 + 1.83 +typedef void (*transform_module_fn_t)(struct qcms_modular_transform *transform, float *src, float *dest, size_t length); 1.84 + 1.85 +struct qcms_modular_transform { 1.86 + struct matrix matrix; 1.87 + float tx, ty, tz; 1.88 + 1.89 + float *input_clut_table_r; 1.90 + float *input_clut_table_g; 1.91 + float *input_clut_table_b; 1.92 + uint16_t input_clut_table_length; 1.93 + float *r_clut; 1.94 + float *g_clut; 1.95 + float *b_clut; 1.96 + uint16_t grid_size; 1.97 + float *output_clut_table_r; 1.98 + float *output_clut_table_g; 1.99 + float *output_clut_table_b; 1.100 + uint16_t output_clut_table_length; 1.101 + 1.102 + uint16_t *output_gamma_lut_r; 1.103 + uint16_t *output_gamma_lut_g; 1.104 + uint16_t *output_gamma_lut_b; 1.105 + 1.106 + size_t output_gamma_lut_r_length; 1.107 + size_t output_gamma_lut_g_length; 1.108 + size_t output_gamma_lut_b_length; 1.109 + 1.110 + transform_module_fn_t transform_module_fn; 1.111 + struct qcms_modular_transform *next_transform; 1.112 +}; 1.113 + 1.114 +typedef int32_t s15Fixed16Number; 1.115 +typedef uint16_t uInt16Number; 1.116 +typedef uint8_t uInt8Number; 1.117 + 1.118 +struct XYZNumber { 1.119 + s15Fixed16Number X; 1.120 + s15Fixed16Number Y; 1.121 + s15Fixed16Number Z; 1.122 +}; 1.123 + 1.124 +struct curveType { 1.125 + uint32_t type; 1.126 + uint32_t count; 1.127 + float parameter[7]; 1.128 + uInt16Number data[]; 1.129 +}; 1.130 + 1.131 +struct lutmABType { 1.132 + uint8_t num_in_channels; 1.133 + uint8_t num_out_channels; 1.134 + // 16 is the upperbound, actual is 0..num_in_channels. 1.135 + uint8_t num_grid_points[16]; 1.136 + 1.137 + s15Fixed16Number e00; 1.138 + s15Fixed16Number e01; 1.139 + s15Fixed16Number e02; 1.140 + s15Fixed16Number e03; 1.141 + s15Fixed16Number e10; 1.142 + s15Fixed16Number e11; 1.143 + s15Fixed16Number e12; 1.144 + s15Fixed16Number e13; 1.145 + s15Fixed16Number e20; 1.146 + s15Fixed16Number e21; 1.147 + s15Fixed16Number e22; 1.148 + s15Fixed16Number e23; 1.149 + 1.150 + // reversed elements (for mBA) 1.151 + bool reversed; 1.152 + 1.153 + float *clut_table; 1.154 + struct curveType *a_curves[10]; 1.155 + struct curveType *b_curves[10]; 1.156 + struct curveType *m_curves[10]; 1.157 + float clut_table_data[]; 1.158 +}; 1.159 + 1.160 +/* should lut8Type and lut16Type be different types? */ 1.161 +struct lutType { // used by lut8Type/lut16Type (mft2) only 1.162 + uint8_t num_input_channels; 1.163 + uint8_t num_output_channels; 1.164 + uint8_t num_clut_grid_points; 1.165 + 1.166 + s15Fixed16Number e00; 1.167 + s15Fixed16Number e01; 1.168 + s15Fixed16Number e02; 1.169 + s15Fixed16Number e10; 1.170 + s15Fixed16Number e11; 1.171 + s15Fixed16Number e12; 1.172 + s15Fixed16Number e20; 1.173 + s15Fixed16Number e21; 1.174 + s15Fixed16Number e22; 1.175 + 1.176 + uint16_t num_input_table_entries; 1.177 + uint16_t num_output_table_entries; 1.178 + 1.179 + float *input_table; 1.180 + float *clut_table; 1.181 + float *output_table; 1.182 + 1.183 + float table_data[]; 1.184 +}; 1.185 +#if 0 1.186 +/* this is from an intial idea of having the struct correspond to the data in 1.187 + * the file. I decided that it wasn't a good idea. 1.188 + */ 1.189 +struct tag_value { 1.190 + uint32_t type; 1.191 + union { 1.192 + struct { 1.193 + uint32_t reserved; 1.194 + struct { 1.195 + s15Fixed16Number X; 1.196 + s15Fixed16Number Y; 1.197 + s15Fixed16Number Z; 1.198 + } XYZNumber; 1.199 + } XYZType; 1.200 + }; 1.201 +}; // I guess we need to pack this? 1.202 +#endif 1.203 + 1.204 +#define RGB_SIGNATURE 0x52474220 1.205 +#define GRAY_SIGNATURE 0x47524159 1.206 +#define XYZ_SIGNATURE 0x58595A20 1.207 +#define LAB_SIGNATURE 0x4C616220 1.208 + 1.209 +struct _qcms_profile { 1.210 + uint32_t class; 1.211 + uint32_t color_space; 1.212 + uint32_t pcs; 1.213 + qcms_intent rendering_intent; 1.214 + struct XYZNumber redColorant; 1.215 + struct XYZNumber blueColorant; 1.216 + struct XYZNumber greenColorant; 1.217 + struct curveType *redTRC; 1.218 + struct curveType *blueTRC; 1.219 + struct curveType *greenTRC; 1.220 + struct curveType *grayTRC; 1.221 + struct lutType *A2B0; 1.222 + struct lutType *B2A0; 1.223 + struct lutmABType *mAB; 1.224 + struct lutmABType *mBA; 1.225 + struct matrix chromaticAdaption; 1.226 + 1.227 + struct precache_output *output_table_r; 1.228 + struct precache_output *output_table_g; 1.229 + struct precache_output *output_table_b; 1.230 +}; 1.231 + 1.232 +#ifdef _MSC_VER 1.233 +#define inline _inline 1.234 +#endif 1.235 + 1.236 +/* produces the nearest float to 'a' with a maximum error 1.237 + * of 1/1024 which happens for large values like 0x40000040 */ 1.238 +static inline float s15Fixed16Number_to_float(s15Fixed16Number a) 1.239 +{ 1.240 + return ((int32_t)a)/65536.f; 1.241 +} 1.242 + 1.243 +static inline s15Fixed16Number double_to_s15Fixed16Number(double v) 1.244 +{ 1.245 + return (int32_t)(v*65536); 1.246 +} 1.247 + 1.248 +static inline float uInt8Number_to_float(uInt8Number a) 1.249 +{ 1.250 + return ((int32_t)a)/255.f; 1.251 +} 1.252 + 1.253 +static inline float uInt16Number_to_float(uInt16Number a) 1.254 +{ 1.255 + return ((int32_t)a)/65535.f; 1.256 +} 1.257 + 1.258 + 1.259 +void precache_release(struct precache_output *p); 1.260 +qcms_bool set_rgb_colorants(qcms_profile *profile, qcms_CIE_xyY white_point, qcms_CIE_xyYTRIPLE primaries); 1.261 +qcms_bool get_rgb_colorants(struct matrix *colorants, qcms_CIE_xyY white_point, qcms_CIE_xyYTRIPLE primaries); 1.262 + 1.263 +void qcms_transform_data_rgb_out_lut_sse2(qcms_transform *transform, 1.264 + unsigned char *src, 1.265 + unsigned char *dest, 1.266 + size_t length); 1.267 +void qcms_transform_data_rgba_out_lut_sse2(qcms_transform *transform, 1.268 + unsigned char *src, 1.269 + unsigned char *dest, 1.270 + size_t length); 1.271 +void qcms_transform_data_rgb_out_lut_sse1(qcms_transform *transform, 1.272 + unsigned char *src, 1.273 + unsigned char *dest, 1.274 + size_t length); 1.275 +void qcms_transform_data_rgba_out_lut_sse1(qcms_transform *transform, 1.276 + unsigned char *src, 1.277 + unsigned char *dest, 1.278 + size_t length); 1.279 + 1.280 +void qcms_transform_data_rgb_out_lut_altivec(qcms_transform *transform, 1.281 + unsigned char *src, 1.282 + unsigned char *dest, 1.283 + size_t length); 1.284 +void qcms_transform_data_rgba_out_lut_altivec(qcms_transform *transform, 1.285 + unsigned char *src, 1.286 + unsigned char *dest, 1.287 + size_t length); 1.288 + 1.289 +extern qcms_bool qcms_supports_iccv4; 1.290 + 1.291 +#ifdef _MSC_VER 1.292 + 1.293 +long __cdecl _InterlockedIncrement(long volatile *); 1.294 +long __cdecl _InterlockedDecrement(long volatile *); 1.295 +#pragma intrinsic(_InterlockedIncrement) 1.296 +#pragma intrinsic(_InterlockedDecrement) 1.297 + 1.298 +#define qcms_atomic_increment(x) _InterlockedIncrement((long volatile *)&x) 1.299 +#define qcms_atomic_decrement(x) _InterlockedDecrement((long volatile*)&x) 1.300 + 1.301 +#else 1.302 + 1.303 +#define qcms_atomic_increment(x) __sync_add_and_fetch(&x, 1) 1.304 +#define qcms_atomic_decrement(x) __sync_sub_and_fetch(&x, 1) 1.305 + 1.306 +#endif 1.307 + 1.308 + 1.309 +#ifdef NATIVE_OUTPUT 1.310 +# define RGB_OUTPUT_COMPONENTS 4 1.311 +# define RGBA_OUTPUT_COMPONENTS 4 1.312 +# ifdef IS_LITTLE_ENDIAN 1.313 +# define OUTPUT_A_INDEX 3 1.314 +# define OUTPUT_R_INDEX 2 1.315 +# define OUTPUT_G_INDEX 1 1.316 +# define OUTPUT_B_INDEX 0 1.317 +# else 1.318 +# define OUTPUT_A_INDEX 0 1.319 +# define OUTPUT_R_INDEX 1 1.320 +# define OUTPUT_G_INDEX 2 1.321 +# define OUTPUT_B_INDEX 3 1.322 +# endif 1.323 +#else 1.324 +# define RGB_OUTPUT_COMPONENTS 3 1.325 +# define RGBA_OUTPUT_COMPONENTS 4 1.326 +# define OUTPUT_R_INDEX 0 1.327 +# define OUTPUT_G_INDEX 1 1.328 +# define OUTPUT_B_INDEX 2 1.329 +# define OUTPUT_A_INDEX 3 1.330 +#endif