@@ -5,9 +5,10 @@ use encoding::pixel::RawPixel;
5
5
use white_point:: { WhitePoint , D65 } ;
6
6
use { clamp, from_f64} ;
7
7
use { Alpha , LabHue , Lch , Xyz } ;
8
- use {
9
- ColorDifference , Component , ComponentWise , FloatComponent , GetHue , Limited , Mix , Pixel , Shade ,
10
- } ;
8
+ use { Component , ComponentWise , FloatComponent , GetHue , Limited , Mix , Pixel , Shade } ;
9
+
10
+ use color_difference:: ColorDifference ;
11
+ use color_difference:: { get_ciede_difference, LabColorDiff } ;
11
12
12
13
/// CIE L\*a\*b\* (CIELAB) with an alpha component. See the [`Laba`
13
14
/// implementation in `Alpha`](struct.Alpha.html#Laba).
@@ -305,13 +306,6 @@ where
305
306
}
306
307
}
307
308
308
- /// CIEDE2000 distance metric for color difference.
309
- pub struct ColorDiff < T : FloatComponent > {
310
- pub l : T ,
311
- pub a : T ,
312
- pub b : T ,
313
- pub chroma : T ,
314
- }
315
309
impl < Wp , T > ColorDifference for Lab < Wp , T >
316
310
where
317
311
T : FloatComponent ,
@@ -322,126 +316,24 @@ where
322
316
fn get_color_difference ( & self , other : & Lab < Wp , T > ) -> Self :: Scalar {
323
317
// Color difference calculation requires Lab and chroma components. This
324
318
// function handles the conversion into those components which are then
325
- // passed to `calculate_color_difference ()`
326
- let self_params = ColorDiff {
319
+ // passed to `get_ciede_difference ()` where calculation is completed.
320
+ let self_params = LabColorDiff {
327
321
l : self . l ,
328
322
a : self . a ,
329
323
b : self . b ,
330
324
chroma : ( self . a * self . a + self . b * self . b ) . sqrt ( ) ,
331
325
} ;
332
- let other_params = ColorDiff {
326
+ let other_params = LabColorDiff {
333
327
l : other. l ,
334
328
a : other. a ,
335
329
b : other. b ,
336
330
chroma : ( other. a * other. a + other. b * other. b ) . sqrt ( ) ,
337
331
} ;
338
332
339
- calculate_color_difference ( & self_params, & other_params)
333
+ get_ciede_difference ( & self_params, & other_params)
340
334
}
341
335
}
342
336
343
- #[ rustfmt:: skip]
344
- pub fn calculate_color_difference < T : FloatComponent > ( this : & ColorDiff < T > , other : & ColorDiff < T > ) -> T {
345
- let c_bar = ( this. chroma + other. chroma ) / from_f64 ( 2.0 ) ;
346
- let c_bar_pow_seven = c_bar * c_bar * c_bar * c_bar * c_bar * c_bar * c_bar;
347
- let twenty_five_pow_seven = from_f64 ( 6103515625.0 ) ;
348
- let pi_over_180 = from_f64 :: < T > ( core:: f64:: consts:: PI / 180.0 ) ;
349
-
350
- let g = from_f64 :: < T > ( 0.5 )
351
- * ( from_f64 :: < T > ( 1.0 )
352
- - ( c_bar_pow_seven / ( c_bar_pow_seven + twenty_five_pow_seven) ) . sqrt ( ) ) ;
353
- let a_one_prime = this. a * ( from_f64 :: < T > ( 1.0 ) + g) ;
354
- let a_two_prime = other. a * ( from_f64 :: < T > ( 1.0 ) + g) ;
355
- let c_one_prime = ( a_one_prime * a_one_prime + this. b * this. b ) . sqrt ( ) ;
356
- let c_two_prime = ( a_two_prime * a_two_prime + other. b * other. b ) . sqrt ( ) ;
357
-
358
- let calc_h_prime = |b : T , a_prime : T | -> T {
359
- if b == T :: zero ( ) && a_prime == T :: zero ( ) {
360
- from_f64 ( 0.0 )
361
- } else {
362
- let result = b. atan2 ( a_prime) . to_degrees ( ) ;
363
- if result < T :: zero ( ) {
364
- result + from_f64 ( 360.0 )
365
- } else {
366
- result
367
- }
368
- }
369
- } ;
370
- let h_one_prime = calc_h_prime ( this. b , a_one_prime) ;
371
- let h_two_prime = calc_h_prime ( other. b , a_two_prime) ;
372
-
373
- let h_prime_difference = ( h_one_prime - h_two_prime) . abs ( ) ;
374
-
375
- let delta_h_prime: T = if c_one_prime == T :: zero ( ) || c_two_prime == T :: zero ( ) {
376
- from_f64 ( 0.0 )
377
- } else {
378
- if h_prime_difference <= from_f64 ( 180.0 ) {
379
- h_two_prime - h_one_prime
380
- } else {
381
- if h_two_prime <= h_one_prime {
382
- h_two_prime - h_one_prime + from_f64 ( 360.0 )
383
- } else {
384
- h_two_prime - h_one_prime - from_f64 ( 360.0 )
385
- }
386
- }
387
- } ;
388
-
389
- let delta_big_h_prime = from_f64 :: < T > ( 2.0 )
390
- * ( c_one_prime * c_two_prime) . sqrt ( )
391
- * ( delta_h_prime / from_f64 ( 2.0 ) * pi_over_180) . sin ( ) ;
392
- let h_bar_prime = if c_one_prime == T :: zero ( ) || c_two_prime == T :: zero ( ) {
393
- h_one_prime + h_two_prime
394
- } else {
395
- if h_prime_difference > from_f64 ( 180.0 ) {
396
- ( h_one_prime + h_two_prime + from_f64 ( 360.0 ) ) / from_f64 ( 2.0 )
397
- } else {
398
- ( h_one_prime + h_two_prime) / from_f64 ( 2.0 )
399
- }
400
- } ;
401
-
402
- let l_bar = ( this. l + other. l ) / from_f64 ( 2.0 ) ;
403
- let c_bar_prime = ( c_one_prime + c_two_prime) / from_f64 ( 2.0 ) ;
404
-
405
- let t: T = from_f64 :: < T > ( 1.0 )
406
- - from_f64 :: < T > ( 0.17 ) * ( ( h_bar_prime - from_f64 ( 30.0 ) ) * pi_over_180) . cos ( )
407
- + from_f64 :: < T > ( 0.24 ) * ( ( h_bar_prime * from_f64 ( 2.0 ) ) * pi_over_180) . cos ( )
408
- + from_f64 :: < T > ( 0.32 ) * ( ( h_bar_prime * from_f64 ( 3.0 ) + from_f64 ( 6.0 ) ) * pi_over_180) . cos ( )
409
- - from_f64 :: < T > ( 0.20 ) * ( ( h_bar_prime * from_f64 ( 4.0 ) - from_f64 ( 63.0 ) ) * pi_over_180) . cos ( ) ;
410
- let s_l = from_f64 :: < T > ( 1.0 )
411
- + ( ( from_f64 :: < T > ( 0.015 ) * ( l_bar - from_f64 ( 50.0 ) ) * ( l_bar - from_f64 ( 50.0 ) ) )
412
- / ( ( l_bar - from_f64 ( 50.0 ) ) * ( l_bar - from_f64 ( 50.0 ) ) + from_f64 ( 20.0 ) ) . sqrt ( ) ) ;
413
- let s_c = from_f64 :: < T > ( 1.0 ) + from_f64 :: < T > ( 0.045 ) * c_bar_prime;
414
- let s_h = from_f64 :: < T > ( 1.0 ) + from_f64 :: < T > ( 0.015 ) * c_bar_prime * t;
415
-
416
- let delta_theta = from_f64 :: < T > ( 30.0 )
417
- * ( -( ( ( h_bar_prime - from_f64 ( 275.0 ) ) / from_f64 ( 25.0 ) )
418
- * ( ( h_bar_prime - from_f64 ( 275.0 ) ) / from_f64 ( 25.0 ) ) ) )
419
- . exp ( ) ;
420
- let c_bar_prime_pow_seven = c_bar_prime
421
- * c_bar_prime
422
- * c_bar_prime
423
- * c_bar_prime
424
- * c_bar_prime
425
- * c_bar_prime
426
- * c_bar_prime;
427
- let r_c: T = from_f64 :: < T > ( 2.0 )
428
- * ( c_bar_prime_pow_seven / ( c_bar_prime_pow_seven + twenty_five_pow_seven) ) . sqrt ( ) ;
429
- let r_t = -r_c * ( from_f64 :: < T > ( 2.0 ) * delta_theta * pi_over_180) . sin ( ) ;
430
-
431
- let one = from_f64 :: < T > ( 1.0 ) ;
432
- let k_l = one;
433
- let k_c = one;
434
- let k_h = one;
435
- let delta_l_prime = other. l - this. l ;
436
- let delta_c_prime = c_two_prime - c_one_prime;
437
-
438
- ( ( delta_l_prime / ( k_l * s_l) ) * ( delta_l_prime / ( k_l * s_l) )
439
- + ( delta_c_prime / ( k_c * s_c) ) * ( delta_c_prime / ( k_c * s_c) )
440
- + ( delta_big_h_prime / ( k_h * s_h) ) * ( delta_big_h_prime / ( k_h * s_h) )
441
- + ( r_t * delta_c_prime * delta_big_h_prime) / ( k_c * s_c * k_h * s_h) )
442
- . sqrt ( )
443
- }
444
-
445
337
impl < Wp , T > ComponentWise for Lab < Wp , T >
446
338
where
447
339
T : FloatComponent ,
0 commit comments