Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(677)

Side by Side Diff: third_party/qcms/src/transform.c

Issue 10407113: Add BGRA output format support to qcms (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/qcms/src/qcmstypes.h ('k') | third_party/qcms/src/transform-sse1.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* vim: set ts=8 sw=8 noexpandtab: */ 1 /* vim: set ts=8 sw=8 noexpandtab: */
2 // qcms 2 // qcms
3 // Copyright (C) 2009 Mozilla Corporation 3 // Copyright (C) 2009 Mozilla Corporation
4 // Copyright (C) 1998-2007 Marti Maria 4 // Copyright (C) 1998-2007 Marti Maria
5 // 5 //
6 // Permission is hereby granted, free of charge, to any person obtaining 6 // Permission is hereby granted, free of charge, to any person obtaining
7 // a copy of this software and associated documentation files (the "Software"), 7 // a copy of this software and associated documentation files (the "Software"),
8 // to deal in the Software without restriction, including without limitation 8 // to deal in the Software without restriction, including without limitation
9 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 // and/or sell copies of the Software, and to permit persons to whom the Softwar e 10 // and/or sell copies of the Software, and to permit persons to whom the Softwar e
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 // Normalize 174 // Normalize
175 return matrix_multiply(chad_inv, matrix_multiply(cone, chad)); 175 return matrix_multiply(chad_inv, matrix_multiply(cone, chad));
176 } 176 }
177 177
178 /* from lcms: cmsAdaptionMatrix */ 178 /* from lcms: cmsAdaptionMatrix */
179 // Returns the final chrmatic adaptation from illuminant FromIll to Illuminant T oIll 179 // Returns the final chrmatic adaptation from illuminant FromIll to Illuminant T oIll
180 // Bradford is assumed 180 // Bradford is assumed
181 static struct matrix 181 static struct matrix
182 adaption_matrix(struct CIE_XYZ source_illumination, struct CIE_XYZ target_illumi nation) 182 adaption_matrix(struct CIE_XYZ source_illumination, struct CIE_XYZ target_illumi nation)
183 { 183 {
184 #if defined (_MSC_VER)
185 #pragma warning(push)
186 /* Disable double to float truncation warning 4305 */
187 #pragma warning(disable:4305)
188 #endif
184 struct matrix lam_rigg = {{ // Bradford matrix 189 struct matrix lam_rigg = {{ // Bradford matrix
185 { 0.8951, 0.2664, -0.1614 }, 190 { 0.8951, 0.2664, -0.1614 },
186 { -0.7502, 1.7135, 0.0367 }, 191 { -0.7502, 1.7135, 0.0367 },
187 { 0.0389, -0.0685, 1.0296 } 192 { 0.0389, -0.0685, 1.0296 }
188 }}; 193 }};
194 #if defined (_MSC_VER)
195 /* Restore warnings */
196 #pragma warning(pop)
197 #endif
189 return compute_chromatic_adaption(source_illumination, target_illuminati on, lam_rigg); 198 return compute_chromatic_adaption(source_illumination, target_illuminati on, lam_rigg);
190 } 199 }
191 200
192 /* from lcms: cmsAdaptMatrixToD50 */ 201 /* from lcms: cmsAdaptMatrixToD50 */
193 static struct matrix adapt_matrix_to_D50(struct matrix r, qcms_CIE_xyY source_wh ite_pt) 202 static struct matrix adapt_matrix_to_D50(struct matrix r, qcms_CIE_xyY source_wh ite_pt)
194 { 203 {
195 struct CIE_XYZ Dn; 204 struct CIE_XYZ Dn;
196 struct matrix Bradford; 205 struct matrix Bradford;
197 206
198 if (source_white_pt.y == 0.0) 207 if (source_white_pt.y == 0.0)
(...skipping 24 matching lines...) Expand all
223 profile->greenColorant.Z = double_to_s15Fixed16Number(colorants.m[2][1]) ; 232 profile->greenColorant.Z = double_to_s15Fixed16Number(colorants.m[2][1]) ;
224 233
225 profile->blueColorant.X = double_to_s15Fixed16Number(colorants.m[0][2]); 234 profile->blueColorant.X = double_to_s15Fixed16Number(colorants.m[0][2]);
226 profile->blueColorant.Y = double_to_s15Fixed16Number(colorants.m[1][2]); 235 profile->blueColorant.Y = double_to_s15Fixed16Number(colorants.m[1][2]);
227 profile->blueColorant.Z = double_to_s15Fixed16Number(colorants.m[2][2]); 236 profile->blueColorant.Z = double_to_s15Fixed16Number(colorants.m[2][2]);
228 237
229 return true; 238 return true;
230 } 239 }
231 240
232 #if 0 241 #if 0
233 static void qcms_transform_data_rgb_out_pow(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) 242 static void qcms_transform_data_rgb_out_pow(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
234 { 243 {
244 const int r_out = output_format.r;
245 const int b_out = output_format.b;
246
235 int i; 247 int i;
236 float (*mat)[4] = transform->matrix; 248 float (*mat)[4] = transform->matrix;
237 for (i=0; i<length; i++) { 249 for (i=0; i<length; i++) {
238 unsigned char device_r = *src++; 250 unsigned char device_r = *src++;
239 unsigned char device_g = *src++; 251 unsigned char device_g = *src++;
240 unsigned char device_b = *src++; 252 unsigned char device_b = *src++;
241 253
242 float linear_r = transform->input_gamma_table_r[device_r]; 254 float linear_r = transform->input_gamma_table_r[device_r];
243 float linear_g = transform->input_gamma_table_g[device_g]; 255 float linear_g = transform->input_gamma_table_g[device_g];
244 float linear_b = transform->input_gamma_table_b[device_b]; 256 float linear_b = transform->input_gamma_table_b[device_b];
245 257
246 float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + m at[2][0]*linear_b; 258 float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + m at[2][0]*linear_b;
247 float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + m at[2][1]*linear_b; 259 float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + m at[2][1]*linear_b;
248 float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + m at[2][2]*linear_b; 260 float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + m at[2][2]*linear_b;
249 261
250 float out_device_r = pow(out_linear_r, transform->out_gamma_r); 262 float out_device_r = pow(out_linear_r, transform->out_gamma_r);
251 float out_device_g = pow(out_linear_g, transform->out_gamma_g); 263 float out_device_g = pow(out_linear_g, transform->out_gamma_g);
252 float out_device_b = pow(out_linear_b, transform->out_gamma_b); 264 float out_device_b = pow(out_linear_b, transform->out_gamma_b);
253 265
254 » » *dest++ = clamp_u8(255*out_device_r); 266 » » dest[r_out] = clamp_u8(out_device_r*255);
255 » » *dest++ = clamp_u8(255*out_device_g); 267 » » dest[1] = clamp_u8(out_device_g*255);
256 » » *dest++ = clamp_u8(255*out_device_b); 268 » » dest[b_out] = clamp_u8(out_device_b*255);
269 » » dest += 3;
257 } 270 }
258 } 271 }
259 #endif 272 #endif
260 273
261 static void qcms_transform_data_gray_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) 274 static void qcms_transform_data_gray_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
262 { 275 {
276 const int r_out = output_format.r;
277 const int b_out = output_format.b;
278
263 unsigned int i; 279 unsigned int i;
264 for (i = 0; i < length; i++) { 280 for (i = 0; i < length; i++) {
265 float out_device_r, out_device_g, out_device_b; 281 float out_device_r, out_device_g, out_device_b;
266 unsigned char device = *src++; 282 unsigned char device = *src++;
267 283
268 float linear = transform->input_gamma_table_gray[device]; 284 float linear = transform->input_gamma_table_gray[device];
269 285
270 out_device_r = lut_interp_linear(linear, transform->output_gamma _lut_r, transform->output_gamma_lut_r_length); 286 » » out_device_r = lut_interp_linear(linear, transform->output_gamma _lut_r, transform->output_gamma_lut_r_length);
271 out_device_g = lut_interp_linear(linear, transform->output_gamma _lut_g, transform->output_gamma_lut_g_length); 287 out_device_g = lut_interp_linear(linear, transform->output_gamma _lut_g, transform->output_gamma_lut_g_length);
272 out_device_b = lut_interp_linear(linear, transform->output_gamma _lut_b, transform->output_gamma_lut_b_length); 288 out_device_b = lut_interp_linear(linear, transform->output_gamma _lut_b, transform->output_gamma_lut_b_length);
273 289
274 » » *dest++ = clamp_u8(out_device_r*255); 290 » » dest[r_out] = clamp_u8(out_device_r*255);
275 » » *dest++ = clamp_u8(out_device_g*255); 291 » » dest[1] = clamp_u8(out_device_g*255);
276 » » *dest++ = clamp_u8(out_device_b*255); 292 » » dest[b_out] = clamp_u8(out_device_b*255);
293 » » dest += 3;
277 } 294 }
278 } 295 }
279 296
280 /* Alpha is not corrected. 297 /* Alpha is not corrected.
281 A rationale for this is found in Alvy Ray's "Should Alpha Be Nonlinear If 298 A rationale for this is found in Alvy Ray's "Should Alpha Be Nonlinear If
282 RGB Is?" Tech Memo 17 (December 14, 1998). 299 RGB Is?" Tech Memo 17 (December 14, 1998).
283 See: ftp://ftp.alvyray.com/Acrobat/17_Nonln.pdf 300 See: ftp://ftp.alvyray.com/Acrobat/17_Nonln.pdf
284 */ 301 */
285 302
286 static void qcms_transform_data_graya_out_lut(qcms_transform *transform, unsigne d char *src, unsigned char *dest, size_t length) 303 static void qcms_transform_data_graya_out_lut(qcms_transform *transform, unsigne d char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
287 { 304 {
305 const int r_out = output_format.r;
306 const int b_out = output_format.b;
307
288 unsigned int i; 308 unsigned int i;
289 for (i = 0; i < length; i++) { 309 for (i = 0; i < length; i++) {
290 float out_device_r, out_device_g, out_device_b; 310 float out_device_r, out_device_g, out_device_b;
291 unsigned char device = *src++; 311 unsigned char device = *src++;
292 unsigned char alpha = *src++; 312 unsigned char alpha = *src++;
293 313
294 float linear = transform->input_gamma_table_gray[device]; 314 float linear = transform->input_gamma_table_gray[device];
295 315
296 out_device_r = lut_interp_linear(linear, transform->output_gamma _lut_r, transform->output_gamma_lut_r_length); 316 » » out_device_r = lut_interp_linear(linear, transform->output_gamma _lut_r, transform->output_gamma_lut_r_length);
297 out_device_g = lut_interp_linear(linear, transform->output_gamma _lut_g, transform->output_gamma_lut_g_length); 317 out_device_g = lut_interp_linear(linear, transform->output_gamma _lut_g, transform->output_gamma_lut_g_length);
298 out_device_b = lut_interp_linear(linear, transform->output_gamma _lut_b, transform->output_gamma_lut_b_length); 318 out_device_b = lut_interp_linear(linear, transform->output_gamma _lut_b, transform->output_gamma_lut_b_length);
299 319
300 » » *dest++ = clamp_u8(out_device_r*255); 320 » » dest[r_out] = clamp_u8(out_device_r*255);
301 » » *dest++ = clamp_u8(out_device_g*255); 321 » » dest[1] = clamp_u8(out_device_g*255);
302 » » *dest++ = clamp_u8(out_device_b*255); 322 » » dest[b_out] = clamp_u8(out_device_b*255);
303 » » *dest++ = alpha; 323 » » dest[3] = alpha;
324 » » dest += 4;
304 } 325 }
305 } 326 }
306 327
307 328
308 static void qcms_transform_data_gray_out_precache(qcms_transform *transform, uns igned char *src, unsigned char *dest, size_t length) 329 static void qcms_transform_data_gray_out_precache(qcms_transform *transform, uns igned char *src, unsigned char *dest, size_t length, qcms_format_type output_for mat)
309 { 330 {
331 const int r_out = output_format.r;
332 const int b_out = output_format.b;
333
310 unsigned int i; 334 unsigned int i;
311 for (i = 0; i < length; i++) { 335 for (i = 0; i < length; i++) {
312 unsigned char device = *src++; 336 unsigned char device = *src++;
313 uint16_t gray; 337 uint16_t gray;
314 338
315 float linear = transform->input_gamma_table_gray[device]; 339 float linear = transform->input_gamma_table_gray[device];
316 340
317 /* we could round here... */ 341 /* we could round here... */
318 gray = linear * PRECACHE_OUTPUT_MAX; 342 gray = linear * PRECACHE_OUTPUT_MAX;
319 343
320 » » *dest++ = transform->output_table_r->data[gray]; 344 » » dest[r_out] = transform->output_table_r->data[gray];
321 » » *dest++ = transform->output_table_g->data[gray]; 345 » » dest[1] = transform->output_table_g->data[gray];
322 » » *dest++ = transform->output_table_b->data[gray]; 346 » » dest[b_out] = transform->output_table_b->data[gray];
347 » » dest += 3;
323 } 348 }
324 } 349 }
325 350
326 static void qcms_transform_data_graya_out_precache(qcms_transform *transform, un signed char *src, unsigned char *dest, size_t length) 351
352 static void qcms_transform_data_graya_out_precache(qcms_transform *transform, un signed char *src, unsigned char *dest, size_t length, qcms_format_type output_fo rmat)
327 { 353 {
354 const int r_out = output_format.r;
355 const int b_out = output_format.b;
356
328 unsigned int i; 357 unsigned int i;
329 for (i = 0; i < length; i++) { 358 for (i = 0; i < length; i++) {
330 unsigned char device = *src++; 359 unsigned char device = *src++;
331 unsigned char alpha = *src++; 360 unsigned char alpha = *src++;
332 uint16_t gray; 361 uint16_t gray;
333 362
334 float linear = transform->input_gamma_table_gray[device]; 363 float linear = transform->input_gamma_table_gray[device];
335 364
336 /* we could round here... */ 365 /* we could round here... */
337 gray = linear * PRECACHE_OUTPUT_MAX; 366 gray = linear * PRECACHE_OUTPUT_MAX;
338 367
339 » » *dest++ = transform->output_table_r->data[gray]; 368 » » dest[r_out] = transform->output_table_r->data[gray];
340 » » *dest++ = transform->output_table_g->data[gray]; 369 » » dest[1] = transform->output_table_g->data[gray];
341 » » *dest++ = transform->output_table_b->data[gray]; 370 » » dest[b_out] = transform->output_table_b->data[gray];
342 » » *dest++ = alpha; 371 » » dest[3] = alpha;
372 » » dest += 4;
343 } 373 }
344 } 374 }
345 375
346 static void qcms_transform_data_rgb_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) 376 static void qcms_transform_data_rgb_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_ format)
347 { 377 {
378 const int r_out = output_format.r;
379 const int b_out = output_format.b;
380
348 unsigned int i; 381 unsigned int i;
349 float (*mat)[4] = transform->matrix; 382 float (*mat)[4] = transform->matrix;
350 for (i = 0; i < length; i++) { 383 for (i = 0; i < length; i++) {
351 unsigned char device_r = *src++; 384 unsigned char device_r = *src++;
352 unsigned char device_g = *src++; 385 unsigned char device_g = *src++;
353 unsigned char device_b = *src++; 386 unsigned char device_b = *src++;
354 uint16_t r, g, b; 387 uint16_t r, g, b;
355 388
356 float linear_r = transform->input_gamma_table_r[device_r]; 389 float linear_r = transform->input_gamma_table_r[device_r];
357 float linear_g = transform->input_gamma_table_g[device_g]; 390 float linear_g = transform->input_gamma_table_g[device_g];
358 float linear_b = transform->input_gamma_table_b[device_b]; 391 float linear_b = transform->input_gamma_table_b[device_b];
359 392
360 float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + m at[2][0]*linear_b; 393 float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + m at[2][0]*linear_b;
361 float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + m at[2][1]*linear_b; 394 float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + m at[2][1]*linear_b;
362 float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + m at[2][2]*linear_b; 395 float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + m at[2][2]*linear_b;
363 396
364 out_linear_r = clamp_float(out_linear_r); 397 out_linear_r = clamp_float(out_linear_r);
365 out_linear_g = clamp_float(out_linear_g); 398 out_linear_g = clamp_float(out_linear_g);
366 out_linear_b = clamp_float(out_linear_b); 399 out_linear_b = clamp_float(out_linear_b);
367 400
368 /* we could round here... */ 401 /* we could round here... */
369 r = out_linear_r * PRECACHE_OUTPUT_MAX; 402 r = out_linear_r * PRECACHE_OUTPUT_MAX;
370 g = out_linear_g * PRECACHE_OUTPUT_MAX; 403 g = out_linear_g * PRECACHE_OUTPUT_MAX;
371 b = out_linear_b * PRECACHE_OUTPUT_MAX; 404 b = out_linear_b * PRECACHE_OUTPUT_MAX;
372 405
373 » » *dest++ = transform->output_table_r->data[r]; 406 » » dest[r_out] = transform->output_table_r->data[r];
374 » » *dest++ = transform->output_table_g->data[g]; 407 » » dest[1] = transform->output_table_g->data[g];
375 » » *dest++ = transform->output_table_b->data[b]; 408 » » dest[b_out] = transform->output_table_b->data[b];
409 » » dest += 3;
376 } 410 }
377 } 411 }
378 412
379 static void qcms_transform_data_rgba_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) 413 static void qcms_transform_data_rgba_out_lut_precache(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output _format)
380 { 414 {
415 const int r_out = output_format.r;
416 const int b_out = output_format.b;
417
381 unsigned int i; 418 unsigned int i;
382 float (*mat)[4] = transform->matrix; 419 float (*mat)[4] = transform->matrix;
383 for (i = 0; i < length; i++) { 420 for (i = 0; i < length; i++) {
384 unsigned char device_r = *src++; 421 unsigned char device_r = *src++;
385 unsigned char device_g = *src++; 422 unsigned char device_g = *src++;
386 unsigned char device_b = *src++; 423 unsigned char device_b = *src++;
387 unsigned char alpha = *src++; 424 unsigned char alpha = *src++;
388 uint16_t r, g, b; 425 uint16_t r, g, b;
389 426
390 float linear_r = transform->input_gamma_table_r[device_r]; 427 float linear_r = transform->input_gamma_table_r[device_r];
391 float linear_g = transform->input_gamma_table_g[device_g]; 428 float linear_g = transform->input_gamma_table_g[device_g];
392 float linear_b = transform->input_gamma_table_b[device_b]; 429 float linear_b = transform->input_gamma_table_b[device_b];
393 430
394 float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + m at[2][0]*linear_b; 431 float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + m at[2][0]*linear_b;
395 float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + m at[2][1]*linear_b; 432 float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + m at[2][1]*linear_b;
396 float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + m at[2][2]*linear_b; 433 float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + m at[2][2]*linear_b;
397 434
398 out_linear_r = clamp_float(out_linear_r); 435 out_linear_r = clamp_float(out_linear_r);
399 out_linear_g = clamp_float(out_linear_g); 436 out_linear_g = clamp_float(out_linear_g);
400 out_linear_b = clamp_float(out_linear_b); 437 out_linear_b = clamp_float(out_linear_b);
401 438
402 /* we could round here... */ 439 /* we could round here... */
403 r = out_linear_r * PRECACHE_OUTPUT_MAX; 440 r = out_linear_r * PRECACHE_OUTPUT_MAX;
404 g = out_linear_g * PRECACHE_OUTPUT_MAX; 441 g = out_linear_g * PRECACHE_OUTPUT_MAX;
405 b = out_linear_b * PRECACHE_OUTPUT_MAX; 442 b = out_linear_b * PRECACHE_OUTPUT_MAX;
406 443
407 » » *dest++ = transform->output_table_r->data[r]; 444 » » dest[r_out] = transform->output_table_r->data[r];
408 » » *dest++ = transform->output_table_g->data[g]; 445 » » dest[1] = transform->output_table_g->data[g];
409 » » *dest++ = transform->output_table_b->data[b]; 446 » » dest[b_out] = transform->output_table_b->data[b];
410 » » *dest++ = alpha; 447 » » dest[3] = alpha;
448 » » dest += 4;
411 } 449 }
412 } 450 }
413 451
414 // Not used 452 // Not used
415 /* 453 /*
416 static void qcms_transform_data_clut(qcms_transform *transform, unsigned char *s rc, unsigned char *dest, size_t length) { 454 static void qcms_transform_data_clut(qcms_transform *transform, unsigned char *s rc, unsigned char *dest, size_t length, qcms_format_type output_format)
455 {
456 » const int r_out = output_format.r;
457 » const int b_out = output_format.b;
458
417 unsigned int i; 459 unsigned int i;
418 int xy_len = 1; 460 int xy_len = 1;
419 int x_len = transform->grid_size; 461 int x_len = transform->grid_size;
420 int len = x_len * x_len; 462 int len = x_len * x_len;
421 float* r_table = transform->r_clut; 463 float* r_table = transform->r_clut;
422 float* g_table = transform->g_clut; 464 float* g_table = transform->g_clut;
423 float* b_table = transform->b_clut; 465 float* b_table = transform->b_clut;
424 466
425 for (i = 0; i < length; i++) { 467 for (i = 0; i < length; i++) {
426 unsigned char in_r = *src++; 468 unsigned char in_r = *src++;
(...skipping 28 matching lines...) Expand all
455 float clut_g = lerp(g_y1, g_y2, z_d); 497 float clut_g = lerp(g_y1, g_y2, z_d);
456 498
457 float b_x1 = lerp(CLU(b_table,x,y,z), CLU(b_table,x_n,y,z), x_d) ; 499 float b_x1 = lerp(CLU(b_table,x,y,z), CLU(b_table,x_n,y,z), x_d) ;
458 float b_x2 = lerp(CLU(b_table,x,y_n,z), CLU(b_table,x_n,y_n,z), x_d); 500 float b_x2 = lerp(CLU(b_table,x,y_n,z), CLU(b_table,x_n,y_n,z), x_d);
459 float b_y1 = lerp(b_x1, b_x2, y_d); 501 float b_y1 = lerp(b_x1, b_x2, y_d);
460 float b_x3 = lerp(CLU(b_table,x,y,z_n), CLU(b_table,x_n,y,z_n), x_d); 502 float b_x3 = lerp(CLU(b_table,x,y,z_n), CLU(b_table,x_n,y,z_n), x_d);
461 float b_x4 = lerp(CLU(b_table,x,y_n,z_n), CLU(b_table,x_n,y_n,z_ n), x_d); 503 float b_x4 = lerp(CLU(b_table,x,y_n,z_n), CLU(b_table,x_n,y_n,z_ n), x_d);
462 float b_y2 = lerp(b_x3, b_x4, y_d); 504 float b_y2 = lerp(b_x3, b_x4, y_d);
463 float clut_b = lerp(b_y1, b_y2, z_d); 505 float clut_b = lerp(b_y1, b_y2, z_d);
464 506
465 » » *dest++ = clamp_u8(clut_r*255.0f); 507 » » dest[r_out] = clamp_u8(clut_r*255.0f);
466 » » *dest++ = clamp_u8(clut_g*255.0f); 508 » » dest[1] = clamp_u8(clut_g*255.0f);
467 » » *dest++ = clamp_u8(clut_b*255.0f); 509 » » dest[b_out] = clamp_u8(clut_b*255.0f);
468 » }» 510 » » dest += 3;
511 » }
469 } 512 }
470 */ 513 */
471 514
472 // Using lcms' tetra interpolation algorithm. 515 // Using lcms' tetra interpolation algorithm.
473 static void qcms_transform_data_tetra_clut_rgba(qcms_transform *transform, unsig ned char *src, unsigned char *dest, size_t length) { 516 static void qcms_transform_data_tetra_clut_rgba(qcms_transform *transform, unsig ned char *src, unsigned char *dest, size_t length, qcms_format_type output_forma t)
517 {
518 » const int r_out = output_format.r;
519 » const int b_out = output_format.b;
520
474 unsigned int i; 521 unsigned int i;
475 int xy_len = 1; 522 int xy_len = 1;
476 int x_len = transform->grid_size; 523 int x_len = transform->grid_size;
477 int len = x_len * x_len; 524 int len = x_len * x_len;
478 float* r_table = transform->r_clut; 525 float* r_table = transform->r_clut;
479 float* g_table = transform->g_clut; 526 float* g_table = transform->g_clut;
480 float* b_table = transform->b_clut; 527 float* b_table = transform->b_clut;
481 float c0_r, c1_r, c2_r, c3_r; 528 float c0_r, c1_r, c2_r, c3_r;
482 float c0_g, c1_g, c2_g, c3_g; 529 float c0_g, c1_g, c2_g, c3_g;
483 float c0_b, c1_b, c2_b, c3_b; 530 float c0_b, c1_b, c2_b, c3_b;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 c2_b = CLU(b_table, x, y_n, z_n) - CLU(b _table, x, y, z_n); 617 c2_b = CLU(b_table, x, y_n, z_n) - CLU(b _table, x, y, z_n);
571 c3_b = CLU(b_table, x, y, z_n) - c0_b; 618 c3_b = CLU(b_table, x, y, z_n) - c0_b;
572 } 619 }
573 } 620 }
574 } 621 }
575 622
576 clut_r = c0_r + c1_r*rx + c2_r*ry + c3_r*rz; 623 clut_r = c0_r + c1_r*rx + c2_r*ry + c3_r*rz;
577 clut_g = c0_g + c1_g*rx + c2_g*ry + c3_g*rz; 624 clut_g = c0_g + c1_g*rx + c2_g*ry + c3_g*rz;
578 clut_b = c0_b + c1_b*rx + c2_b*ry + c3_b*rz; 625 clut_b = c0_b + c1_b*rx + c2_b*ry + c3_b*rz;
579 626
580 » » *dest++ = clamp_u8(clut_r*255.0f); 627 » » dest[r_out] = clamp_u8(clut_r*255.0f);
581 » » *dest++ = clamp_u8(clut_g*255.0f); 628 » » dest[1] = clamp_u8(clut_g*255.0f);
582 » » *dest++ = clamp_u8(clut_b*255.0f); 629 » » dest[b_out] = clamp_u8(clut_b*255.0f);
583 » » *dest++ = in_a; 630 » » dest[3] = in_a;
584 » }» 631 » » dest += 4;
632 » }
585 } 633 }
586 634
587 // Using lcms' tetra interpolation code. 635 // Using lcms' tetra interpolation code.
588 static void qcms_transform_data_tetra_clut(qcms_transform *transform, unsigned c har *src, unsigned char *dest, size_t length) { 636 static void qcms_transform_data_tetra_clut(qcms_transform *transform, unsigned c har *src, unsigned char *dest, size_t length, qcms_format_type output_format)
637 {
638 » const int r_out = output_format.r;
639 » const int b_out = output_format.b;
640
589 unsigned int i; 641 unsigned int i;
590 int xy_len = 1; 642 int xy_len = 1;
591 int x_len = transform->grid_size; 643 int x_len = transform->grid_size;
592 int len = x_len * x_len; 644 int len = x_len * x_len;
593 float* r_table = transform->r_clut; 645 float* r_table = transform->r_clut;
594 float* g_table = transform->g_clut; 646 float* g_table = transform->g_clut;
595 float* b_table = transform->b_clut; 647 float* b_table = transform->b_clut;
596 float c0_r, c1_r, c2_r, c3_r; 648 float c0_r, c1_r, c2_r, c3_r;
597 float c0_g, c1_g, c2_g, c3_g; 649 float c0_g, c1_g, c2_g, c3_g;
598 float c0_b, c1_b, c2_b, c3_b; 650 float c0_b, c1_b, c2_b, c3_b;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 c2_b = CLU(b_table, x, y_n, z_n) - CLU(b _table, x, y, z_n); 736 c2_b = CLU(b_table, x, y_n, z_n) - CLU(b _table, x, y, z_n);
685 c3_b = CLU(b_table, x, y, z_n) - c0_b; 737 c3_b = CLU(b_table, x, y, z_n) - c0_b;
686 } 738 }
687 } 739 }
688 } 740 }
689 741
690 clut_r = c0_r + c1_r*rx + c2_r*ry + c3_r*rz; 742 clut_r = c0_r + c1_r*rx + c2_r*ry + c3_r*rz;
691 clut_g = c0_g + c1_g*rx + c2_g*ry + c3_g*rz; 743 clut_g = c0_g + c1_g*rx + c2_g*ry + c3_g*rz;
692 clut_b = c0_b + c1_b*rx + c2_b*ry + c3_b*rz; 744 clut_b = c0_b + c1_b*rx + c2_b*ry + c3_b*rz;
693 745
694 » » *dest++ = clamp_u8(clut_r*255.0f); 746 » » dest[r_out] = clamp_u8(clut_r*255.0f);
695 » » *dest++ = clamp_u8(clut_g*255.0f); 747 » » dest[1] = clamp_u8(clut_g*255.0f);
696 » » *dest++ = clamp_u8(clut_b*255.0f); 748 » » dest[b_out] = clamp_u8(clut_b*255.0f);
697 » }» 749 » » dest += 3;
750 » }
698 } 751 }
699 752
700 static void qcms_transform_data_rgb_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) 753 static void qcms_transform_data_rgb_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
701 { 754 {
755 const int r_out = output_format.r;
756 const int b_out = output_format.b;
757
702 unsigned int i; 758 unsigned int i;
703 float (*mat)[4] = transform->matrix; 759 float (*mat)[4] = transform->matrix;
704 for (i = 0; i < length; i++) { 760 for (i = 0; i < length; i++) {
705 unsigned char device_r = *src++; 761 unsigned char device_r = *src++;
706 unsigned char device_g = *src++; 762 unsigned char device_g = *src++;
707 unsigned char device_b = *src++; 763 unsigned char device_b = *src++;
708 float out_device_r, out_device_g, out_device_b; 764 float out_device_r, out_device_g, out_device_b;
709 765
710 float linear_r = transform->input_gamma_table_r[device_r]; 766 float linear_r = transform->input_gamma_table_r[device_r];
711 float linear_g = transform->input_gamma_table_g[device_g]; 767 float linear_g = transform->input_gamma_table_g[device_g];
712 float linear_b = transform->input_gamma_table_b[device_b]; 768 float linear_b = transform->input_gamma_table_b[device_b];
713 769
714 float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + m at[2][0]*linear_b; 770 float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + m at[2][0]*linear_b;
715 float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + m at[2][1]*linear_b; 771 float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + m at[2][1]*linear_b;
716 float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + m at[2][2]*linear_b; 772 float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + m at[2][2]*linear_b;
717 773
718 out_linear_r = clamp_float(out_linear_r); 774 out_linear_r = clamp_float(out_linear_r);
719 out_linear_g = clamp_float(out_linear_g); 775 out_linear_g = clamp_float(out_linear_g);
720 out_linear_b = clamp_float(out_linear_b); 776 out_linear_b = clamp_float(out_linear_b);
721 777
722 out_device_r = lut_interp_linear(out_linear_r, 778 out_device_r = lut_interp_linear(out_linear_r,
723 transform->output_gamma_lut_r, transform->output _gamma_lut_r_length); 779 transform->output_gamma_lut_r, transform->output _gamma_lut_r_length);
724 out_device_g = lut_interp_linear(out_linear_g, 780 out_device_g = lut_interp_linear(out_linear_g,
725 transform->output_gamma_lut_g, transform->output _gamma_lut_g_length); 781 transform->output_gamma_lut_g, transform->output _gamma_lut_g_length);
726 out_device_b = lut_interp_linear(out_linear_b, 782 out_device_b = lut_interp_linear(out_linear_b,
727 transform->output_gamma_lut_b, transform->output _gamma_lut_b_length); 783 transform->output_gamma_lut_b, transform->output _gamma_lut_b_length);
728 784
729 » » *dest++ = clamp_u8(out_device_r*255); 785 » » dest[r_out] = clamp_u8(out_device_r*255);
730 » » *dest++ = clamp_u8(out_device_g*255); 786 » » dest[1] = clamp_u8(out_device_g*255);
731 » » *dest++ = clamp_u8(out_device_b*255); 787 » » dest[b_out] = clamp_u8(out_device_b*255);
788 » » dest += 3;
732 } 789 }
733 } 790 }
734 791
735 static void qcms_transform_data_rgba_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length) 792 static void qcms_transform_data_rgba_out_lut(qcms_transform *transform, unsigned char *src, unsigned char *dest, size_t length, qcms_format_type output_format)
736 { 793 {
794 const int r_out = output_format.r;
795 const int b_out = output_format.b;
796
737 unsigned int i; 797 unsigned int i;
738 float (*mat)[4] = transform->matrix; 798 float (*mat)[4] = transform->matrix;
739 for (i = 0; i < length; i++) { 799 for (i = 0; i < length; i++) {
740 unsigned char device_r = *src++; 800 unsigned char device_r = *src++;
741 unsigned char device_g = *src++; 801 unsigned char device_g = *src++;
742 unsigned char device_b = *src++; 802 unsigned char device_b = *src++;
743 unsigned char alpha = *src++; 803 unsigned char alpha = *src++;
744 float out_device_r, out_device_g, out_device_b; 804 float out_device_r, out_device_g, out_device_b;
745 805
746 float linear_r = transform->input_gamma_table_r[device_r]; 806 float linear_r = transform->input_gamma_table_r[device_r];
747 float linear_g = transform->input_gamma_table_g[device_g]; 807 float linear_g = transform->input_gamma_table_g[device_g];
748 float linear_b = transform->input_gamma_table_b[device_b]; 808 float linear_b = transform->input_gamma_table_b[device_b];
749 809
750 float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + m at[2][0]*linear_b; 810 float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + m at[2][0]*linear_b;
751 float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + m at[2][1]*linear_b; 811 float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + m at[2][1]*linear_b;
752 float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + m at[2][2]*linear_b; 812 float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + m at[2][2]*linear_b;
753 813
754 out_linear_r = clamp_float(out_linear_r); 814 out_linear_r = clamp_float(out_linear_r);
755 out_linear_g = clamp_float(out_linear_g); 815 out_linear_g = clamp_float(out_linear_g);
756 out_linear_b = clamp_float(out_linear_b); 816 out_linear_b = clamp_float(out_linear_b);
757 817
758 out_device_r = lut_interp_linear(out_linear_r, 818 out_device_r = lut_interp_linear(out_linear_r,
759 transform->output_gamma_lut_r, transform->output _gamma_lut_r_length); 819 transform->output_gamma_lut_r, transform->output _gamma_lut_r_length);
760 out_device_g = lut_interp_linear(out_linear_g, 820 out_device_g = lut_interp_linear(out_linear_g,
761 transform->output_gamma_lut_g, transform->output _gamma_lut_g_length); 821 transform->output_gamma_lut_g, transform->output _gamma_lut_g_length);
762 out_device_b = lut_interp_linear(out_linear_b, 822 out_device_b = lut_interp_linear(out_linear_b,
763 transform->output_gamma_lut_b, transform->output _gamma_lut_b_length); 823 transform->output_gamma_lut_b, transform->output _gamma_lut_b_length);
764 824
765 » » *dest++ = clamp_u8(out_device_r*255); 825 » » dest[r_out] = clamp_u8(out_device_r*255);
766 » » *dest++ = clamp_u8(out_device_g*255); 826 » » dest[1] = clamp_u8(out_device_g*255);
767 » » *dest++ = clamp_u8(out_device_b*255); 827 » » dest[b_out] = clamp_u8(out_device_b*255);
768 » » *dest++ = alpha; 828 » » dest[3] = alpha;
829 » » dest += 4;
769 } 830 }
770 } 831 }
771 832
772 #if 0 833 #if 0
773 static void qcms_transform_data_rgb_out_linear(qcms_transform *transform, unsign ed char *src, unsigned char *dest, size_t length) 834 static void qcms_transform_data_rgb_out_linear(qcms_transform *transform, unsign ed char *src, unsigned char *dest, size_t length, qcms_format_type output_format )
774 { 835 {
836 const int r_out = output_format.r;
837 const int b_out = output_format.b;
838
775 int i; 839 int i;
776 float (*mat)[4] = transform->matrix; 840 float (*mat)[4] = transform->matrix;
777 for (i = 0; i < length; i++) { 841 for (i = 0; i < length; i++) {
778 unsigned char device_r = *src++; 842 unsigned char device_r = *src++;
779 unsigned char device_g = *src++; 843 unsigned char device_g = *src++;
780 unsigned char device_b = *src++; 844 unsigned char device_b = *src++;
781 845
782 float linear_r = transform->input_gamma_table_r[device_r]; 846 float linear_r = transform->input_gamma_table_r[device_r];
783 float linear_g = transform->input_gamma_table_g[device_g]; 847 float linear_g = transform->input_gamma_table_g[device_g];
784 float linear_b = transform->input_gamma_table_b[device_b]; 848 float linear_b = transform->input_gamma_table_b[device_b];
785 849
786 float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + m at[2][0]*linear_b; 850 float out_linear_r = mat[0][0]*linear_r + mat[1][0]*linear_g + m at[2][0]*linear_b;
787 float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + m at[2][1]*linear_b; 851 float out_linear_g = mat[0][1]*linear_r + mat[1][1]*linear_g + m at[2][1]*linear_b;
788 float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + m at[2][2]*linear_b; 852 float out_linear_b = mat[0][2]*linear_r + mat[1][2]*linear_g + m at[2][2]*linear_b;
789 853
790 » » *dest++ = clamp_u8(out_linear_r*255); 854 » » dest[r_out] = clamp_u8(out_linear_r*255);
791 » » *dest++ = clamp_u8(out_linear_g*255); 855 » » dest[1] = clamp_u8(out_linear_g*255);
792 » » *dest++ = clamp_u8(out_linear_b*255); 856 » » dest[b_out] = clamp_u8(out_linear_b*255);
857 » » dest += 3;
793 } 858 }
794 } 859 }
795 #endif 860 #endif
796 861
797 static struct precache_output *precache_reference(struct precache_output *p) 862 static struct precache_output *precache_reference(struct precache_output *p)
798 { 863 {
799 p->ref_count++; 864 p->ref_count++;
800 return p; 865 return p;
801 } 866 }
802 867
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
1255 } 1320 }
1256 return transform; 1321 return transform;
1257 } 1322 }
1258 1323
1259 #if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__) 1324 #if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
1260 /* we need this to avoid crashes when gcc assumes the stack is 128bit aligned */ 1325 /* we need this to avoid crashes when gcc assumes the stack is 128bit aligned */
1261 __attribute__((__force_align_arg_pointer__)) 1326 __attribute__((__force_align_arg_pointer__))
1262 #endif 1327 #endif
1263 void qcms_transform_data(qcms_transform *transform, void *src, void *dest, size_ t length) 1328 void qcms_transform_data(qcms_transform *transform, void *src, void *dest, size_ t length)
1264 { 1329 {
1265 » transform->transform_fn(transform, src, dest, length); 1330 » static const struct _qcms_format_type output_rgbx = { 0, 2 };
1331
1332 » transform->transform_fn(transform, src, dest, length, output_rgbx);
1333 }
1334
1335 void qcms_transform_data_type(qcms_transform *transform, void *src, void *dest, size_t length, qcms_output_type type)
1336 {
1337 » static const struct _qcms_format_type output_rgbx = { 0, 2 };
1338 » static const struct _qcms_format_type output_bgrx = { 2, 0 };
1339
1340 » transform->transform_fn(transform, src, dest, length, type == QCMS_OUTPU T_BGRX ? output_bgrx : output_rgbx);
1266 } 1341 }
1267 1342
1268 qcms_bool qcms_supports_iccv4; 1343 qcms_bool qcms_supports_iccv4;
1269 void qcms_enable_iccv4() 1344 void qcms_enable_iccv4()
1270 { 1345 {
1271 qcms_supports_iccv4 = true; 1346 qcms_supports_iccv4 = true;
1272 } 1347 }
OLDNEW
« no previous file with comments | « third_party/qcms/src/qcmstypes.h ('k') | third_party/qcms/src/transform-sse1.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698