@@ -8,9 +8,10 @@ use std::fs::File;
88use std:: slice;
99use std:: collections:: HashMap ;
1010use std:: cmp:: { min, max} ;
11+ use std:: f32:: consts:: TAU ;
1112
1213use exr:: prelude:: simple_image;
13- use half :: f16 ;
14+ use color_space :: { Rgb , Hsv } ;
1415
1516pub enum DataType {
1617 NONE ,
@@ -27,10 +28,9 @@ pub struct DataExport {
2728 pub rgb : Vec < u8 > ,
2829 pub palette : Vec < ( u8 , u8 , u8 ) > ,
2930 pub iterations : Vec < u32 > ,
30- pub smooth_f16 : Vec < f16 > ,
31- pub smooth_f32 : Vec < f32 > ,
32- pub distance_x : Vec < f16 > ,
33- pub distance_y : Vec < f16 > ,
31+ pub smooth : Vec < f32 > ,
32+ pub distance_x : Vec < f32 > ,
33+ pub distance_y : Vec < f32 > ,
3434 pub display_glitches : bool ,
3535 pub iteration_division : f32 ,
3636 pub iteration_offset : f32 ,
@@ -42,8 +42,7 @@ pub struct DataExport {
4242impl DataExport {
4343 pub fn new ( image_width : usize , image_height : usize , display_glitches : bool , data_type : DataType , palette : Vec < ( u8 , u8 , u8 ) > , iteration_division : f32 , iteration_offset : f32 , analytic_derivative : bool ) -> Self {
4444 let mut rgb = Vec :: new ( ) ;
45- let mut smooth_f16 = Vec :: new ( ) ;
46- let mut smooth_f32 = Vec :: new ( ) ;
45+ let mut smooth = Vec :: new ( ) ;
4746 let mut distance_x = Vec :: new ( ) ;
4847 let mut distance_y = Vec :: new ( ) ;
4948
@@ -54,23 +53,23 @@ impl DataExport {
5453 } ,
5554 DataType :: GUI => {
5655 rgb = vec ! [ 0u8 ; image_width * image_height * 3 ] ;
57- smooth_f32 = vec ! [ 0.0f32 ; image_width * image_height] ;
58- distance_x = vec ! [ f16 :: ZERO ; image_width * image_height] ;
59- distance_y = vec ! [ f16 :: ZERO ; image_width * image_height] ;
56+ smooth = vec ! [ 0.0f32 ; image_width * image_height] ;
57+ distance_x = vec ! [ 0.0f32 ; image_width * image_height] ;
58+ distance_y = vec ! [ 0.0f32 ; image_width * image_height] ;
6059 }
6160 DataType :: RAW => {
62- smooth_f16 = vec ! [ f16 :: ZERO ; image_width * image_height] ;
63- distance_x = vec ! [ f16 :: ZERO ; image_width * image_height] ;
64- distance_y = vec ! [ f16 :: ZERO ; image_width * image_height] ;
61+ smooth = vec ! [ 0.0f32 ; image_width * image_height] ;
62+ distance_x = vec ! [ 0.0f32 ; image_width * image_height] ;
63+ distance_y = vec ! [ 0.0f32 ; image_width * image_height] ;
6564 } ,
6665 DataType :: KFB => {
67- smooth_f32 = vec ! [ 0.0f32 ; image_width * image_height] ;
66+ smooth = vec ! [ 0.0f32 ; image_width * image_height] ;
6867 } ,
6968 DataType :: BOTH => {
7069 rgb = vec ! [ 0u8 ; image_width * image_height * 3 ] ;
71- smooth_f16 = vec ! [ f16 :: ZERO ; image_width * image_height] ;
72- distance_x = vec ! [ f16 :: ZERO ; image_width * image_height] ;
73- distance_y = vec ! [ f16 :: ZERO ; image_width * image_height] ;
70+ smooth = vec ! [ 0.0f32 ; image_width * image_height] ;
71+ distance_x = vec ! [ 0.0f32 ; image_width * image_height] ;
72+ distance_y = vec ! [ 0.0f32 ; image_width * image_height] ;
7473 }
7574 }
7675
@@ -80,8 +79,7 @@ impl DataExport {
8079 rgb,
8180 palette,
8281 iterations : vec ! [ 0u32 ; image_width * image_height] ,
83- smooth_f16,
84- smooth_f32,
82+ smooth,
8583 distance_x,
8684 distance_y,
8785 display_glitches,
@@ -156,7 +154,7 @@ impl DataExport {
156154 let z_norm = ( reference. reference_data [ pixel. iteration - reference. start_iteration ] . z_fixed + pixel. delta_current . mantissa ) . norm_sqr ( ) as f32 ;
157155 let smooth = 1.0 - ( z_norm. ln ( ) / escape_radius_ln) . log2 ( ) ;
158156
159- self . smooth_f32 [ k] = smooth;
157+ self . smooth [ k] = smooth;
160158
161159 if self . analytic_derivative {
162160 let temp1 = reference. reference_data [ pixel. iteration - reference. start_iteration ] . z_extended + pixel. delta_current ;
@@ -185,8 +183,8 @@ impl DataExport {
185183
186184 let output = num / ComplexFixed :: new ( den_1, den_2) ;
187185
188- self . distance_x [ k] = f16 :: from_f64 ( output. re ) ;
189- self . distance_y [ k] = f16 :: from_f64 ( output. im ) ;
186+ self . distance_x [ k] = output. re as f32 ;
187+ self . distance_y [ k] = output. im as f32 ;
190188 } ;
191189
192190 self . colour_index ( k)
@@ -206,7 +204,7 @@ impl DataExport {
206204 } ;
207205
208206 let z_norm = ( reference. reference_data [ pixel. iteration - reference. start_iteration ] . z_fixed + pixel. delta_current . mantissa ) . norm_sqr ( ) as f32 ;
209- self . smooth_f16 [ k] = f16 :: from_f32 ( 1.0 - ( z_norm. ln ( ) / escape_radius_ln) . log2 ( ) ) ;
207+ self . smooth [ k] = 1.0 - ( z_norm. ln ( ) / escape_radius_ln) . log2 ( ) ;
210208
211209 if self . analytic_derivative && pixel. iteration < self . maximum_iteration {
212210 let temp1 = reference. reference_data [ pixel. iteration - reference. start_iteration ] . z_extended + pixel. delta_current ;
@@ -235,8 +233,8 @@ impl DataExport {
235233
236234 let output = num / ComplexFixed :: new ( den_1, den_2) ;
237235
238- self . distance_x [ k] = f16 :: from_f64 ( output. re ) ;
239- self . distance_y [ k] = f16 :: from_f64 ( output. im ) ;
236+ self . distance_x [ k] = output. re as f32 ;
237+ self . distance_y [ k] = output. im as f32 ;
240238 }
241239 }
242240 } ,
@@ -253,7 +251,7 @@ impl DataExport {
253251 } ;
254252
255253 let z_norm = ( reference. reference_data [ pixel. iteration - reference. start_iteration ] . z_fixed + pixel. delta_current . mantissa ) . norm_sqr ( ) as f32 ;
256- self . smooth_f32 [ k] = 1.0 - ( z_norm. ln ( ) / escape_radius_ln) . log2 ( ) ;
254+ self . smooth [ k] = 1.0 - ( z_norm. ln ( ) / escape_radius_ln) . log2 ( ) ;
257255 }
258256 } ,
259257 DataType :: BOTH => {
@@ -276,7 +274,7 @@ impl DataExport {
276274 let z_norm = ( reference. reference_data [ pixel. iteration - reference. start_iteration ] . z_fixed + pixel. delta_current . mantissa ) . norm_sqr ( ) as f32 ;
277275 let smooth = 1.0 - ( z_norm. ln ( ) / escape_radius_ln) . log2 ( ) ;
278276
279- self . smooth_f16 [ k] = f16 :: from_f32 ( smooth) ;
277+ self . smooth [ k] = smooth;
280278
281279 if self . analytic_derivative {
282280 let temp1 = reference. reference_data [ pixel. iteration - reference. start_iteration ] . z_extended + pixel. delta_current ;
@@ -305,8 +303,8 @@ impl DataExport {
305303
306304 let output = num / ComplexFixed :: new ( den_1, den_2) ;
307305
308- self . distance_x [ k] = f16 :: from_f64 ( output. re ) ;
309- self . distance_y [ k] = f16 :: from_f64 ( output. im ) ;
306+ self . distance_x [ k] = output. re as f32 ;
307+ self . distance_y [ k] = output. im as f32 ;
310308 } ;
311309
312310 self . colour_index ( k)
@@ -367,11 +365,11 @@ impl DataExport {
367365
368366 pub fn save_raw ( & mut self , filename : & str , approximation_order : usize , zoom : & str ) {
369367 let iterations = simple_image:: Channel :: non_color_data ( simple_image:: Text :: from ( "N" ) . unwrap ( ) , simple_image:: Samples :: U32 ( self . iterations . clone ( ) ) ) ;
370- let smooth = simple_image:: Channel :: non_color_data ( simple_image:: Text :: from ( "NF" ) . unwrap ( ) , simple_image:: Samples :: F16 ( self . smooth_f16 . clone ( ) ) ) ;
368+ let smooth = simple_image:: Channel :: non_color_data ( simple_image:: Text :: from ( "NF" ) . unwrap ( ) , simple_image:: Samples :: F32 ( self . smooth . clone ( ) ) ) ;
371369
372370 let channels = if self . analytic_derivative {
373- let distance_x = simple_image:: Channel :: non_color_data ( simple_image:: Text :: from ( "DEX" ) . unwrap ( ) , simple_image:: Samples :: F16 ( self . distance_x . clone ( ) ) ) ;
374- let distance_y = simple_image:: Channel :: non_color_data ( simple_image:: Text :: from ( "DEY" ) . unwrap ( ) , simple_image:: Samples :: F16 ( self . distance_y . clone ( ) ) ) ;
371+ let distance_x = simple_image:: Channel :: non_color_data ( simple_image:: Text :: from ( "DEX" ) . unwrap ( ) , simple_image:: Samples :: F32 ( self . distance_x . clone ( ) ) ) ;
372+ let distance_y = simple_image:: Channel :: non_color_data ( simple_image:: Text :: from ( "DEY" ) . unwrap ( ) , simple_image:: Samples :: F32 ( self . distance_y . clone ( ) ) ) ;
375373
376374 smallvec:: smallvec![ iterations, smooth, distance_x, distance_y]
377375 } else {
@@ -430,7 +428,7 @@ impl DataExport {
430428 } ) . unwrap ( ) ;
431429
432430 file. write_all ( unsafe {
433- slice:: from_raw_parts ( self . smooth_f32 . as_ptr ( ) as * const u8 , self . iterations . len ( ) * 4 )
431+ slice:: from_raw_parts ( self . smooth . as_ptr ( ) as * const u8 , self . iterations . len ( ) * 4 )
434432 } ) . unwrap ( ) ;
435433
436434 }
@@ -444,26 +442,26 @@ impl DataExport {
444442 DataType :: GUI => {
445443 self . rgb = vec ! [ 0u8 ; self . image_width * self . image_height * 3 ] ;
446444 self . iterations = vec ! [ 0xFFFFFFFF ; self . image_width * self . image_height] ;
447- self . smooth_f32 = vec ! [ 0.0f32 ; self . image_width * self . image_height] ;
448- self . distance_x = vec ! [ f16 :: ZERO ; self . image_width * self . image_height] ;
449- self . distance_y = vec ! [ f16 :: ZERO ; self . image_width * self . image_height] ;
445+ self . smooth = vec ! [ 0.0f32 ; self . image_width * self . image_height] ;
446+ self . distance_x = vec ! [ 0.0f32 ; self . image_width * self . image_height] ;
447+ self . distance_y = vec ! [ 0.0f32 ; self . image_width * self . image_height] ;
450448 }
451449 DataType :: RAW => {
452450 self . iterations = vec ! [ 0xFFFFFFFF ; self . image_width * self . image_height] ;
453- self . smooth_f16 = vec ! [ f16 :: ZERO ; self . image_width * self . image_height] ;
454- self . distance_x = vec ! [ f16 :: ZERO ; self . image_width * self . image_height] ;
455- self . distance_y = vec ! [ f16 :: ZERO ; self . image_width * self . image_height] ;
451+ self . smooth = vec ! [ 0.0f32 ; self . image_width * self . image_height] ;
452+ self . distance_x = vec ! [ 0.0f32 ; self . image_width * self . image_height] ;
453+ self . distance_y = vec ! [ 0.0f32 ; self . image_width * self . image_height] ;
456454 } ,
457455 DataType :: KFB => {
458456 self . iterations = vec ! [ 0xFFFFFFFF ; self . image_width * self . image_height] ;
459- self . smooth_f32 = vec ! [ 0.0f32 ; self . image_width * self . image_height] ;
457+ self . smooth = vec ! [ 0.0f32 ; self . image_width * self . image_height] ;
460458 } ,
461459 DataType :: BOTH => {
462460 self . rgb = vec ! [ 0u8 ; self . image_width * self . image_height * 3 ] ;
463461 self . iterations = vec ! [ 0xFFFFFFFF ; self . image_width * self . image_height] ;
464- self . smooth_f16 = vec ! [ f16 :: ZERO ; self . image_width * self . image_height] ;
465- self . distance_x = vec ! [ f16 :: ZERO ; self . image_width * self . image_height] ;
466- self . distance_y = vec ! [ f16 :: ZERO ; self . image_width * self . image_height] ;
462+ self . smooth = vec ! [ 0.0f32 ; self . image_width * self . image_height] ;
463+ self . distance_x = vec ! [ 0.0f32 ; self . image_width * self . image_height] ;
464+ self . distance_y = vec ! [ 0.0f32 ; self . image_width * self . image_height] ;
467465 }
468466 }
469467 }
@@ -493,11 +491,11 @@ impl DataExport {
493491 let k_right = pixel. image_y * self . image_width + min ( self . image_width - 2 , pixel. image_x ) + 1 ;
494492
495493 self . iterations [ k] = ( self . iterations [ k_up] + self . iterations [ k_down] + self . iterations [ k_left] + self . iterations [ k_right] ) / 4 ;
496- self . smooth_f32 [ k] = ( self . smooth_f32 [ k_up] + self . smooth_f32 [ k_down] + self . smooth_f32 [ k_left] + self . smooth_f32 [ k_right] ) / 4.0 ;
494+ self . smooth [ k] = ( self . smooth [ k_up] + self . smooth [ k_down] + self . smooth [ k_left] + self . smooth [ k_right] ) / 4.0 ;
497495
498496 if self . analytic_derivative {
499- self . distance_x [ k] = f16 :: from_f32 ( ( f32 :: from ( self . distance_x [ k_up] ) + f32 :: from ( self . distance_x [ k_down] ) + f32 :: from ( self . distance_x [ k_left] ) + f32 :: from ( self . distance_x [ k_right] ) ) / 4.0 ) ;
500- self . distance_y [ k] = f16 :: from_f32 ( ( f32 :: from ( self . distance_y [ k_up] ) + f32 :: from ( self . distance_y [ k_down] ) + f32 :: from ( self . distance_y [ k_left] ) + f32 :: from ( self . distance_y [ k_right] ) ) / 4.0 ) ;
497+ self . distance_x [ k] = ( self . distance_x [ k_up] + self . distance_x [ k_down] + self . distance_x [ k_left] + self . distance_x [ k_right] ) / 4.0 ;
498+ self . distance_y [ k] = ( self . distance_y [ k_up] + self . distance_y [ k_down] + self . distance_y [ k_left] + self . distance_y [ k_right] ) / 4.0 ;
501499 }
502500
503501 self . colour_index ( k) ;
@@ -514,15 +512,32 @@ impl DataExport {
514512 self . rgb [ 3 * i + 1 ] = 0u8 ;
515513 self . rgb [ 3 * i + 2 ] = 0u8 ;
516514 } else if self . analytic_derivative {
517- let output = ( ( f32:: from ( self . distance_x [ i] ) ) . powi ( 2 ) + ( f32:: from ( self . distance_y [ i] ) ) . powi ( 2 ) ) . sqrt ( ) ;
515+ let length = ( self . distance_x [ i] . powi ( 2 ) + self . distance_y [ i] . powi ( 2 ) ) . sqrt ( ) ;
516+
517+ // colouring algorithm based on 'rainbow_fringe' by claude
518+ let angle = self . distance_y [ i] . atan2 ( self . distance_x [ i] ) ;
518519
519- let out = ( 255.0 * output. tanh ( ) ) as u8 ;
520+ let mut hue = angle / TAU ;
521+ hue -= hue. floor ( ) ;
520522
521- self . rgb [ 3 * i] = out as u8 ;
522- self . rgb [ 3 * i + 1 ] = out as u8 ;
523- self . rgb [ 3 * i + 2 ] = out as u8 ;
523+ let saturation = ( 1.0 / ( 1.0 + length) ) . max ( 0.0 ) . min ( 1.0 ) ;
524+ let value = length. max ( 0.0 ) . min ( 1.0 ) ;
525+
526+ let hsv = Hsv :: new ( hue as f64 * 360.0 , saturation as f64 , value as f64 ) ;
527+ let rgb = Rgb :: from ( hsv) ;
528+
529+ self . rgb [ 3 * i] = rgb. r as u8 ;
530+ self . rgb [ 3 * i + 1 ] = rgb. g as u8 ;
531+ self . rgb [ 3 * i + 2 ] = rgb. b as u8 ;
532+
533+ // default colouring algorithm
534+ // let out = (255.0 * length) as u8;
535+
536+ // self.rgb[3 * i] = out as u8;
537+ // self.rgb[3 * i + 1] = out as u8;
538+ // self.rgb[3 * i + 2] = out as u8;
524539 } else {
525- let temp = ( ( self . iterations [ i] as f32 + self . smooth_f32 [ i] ) / self . iteration_division ) + self . iteration_offset ;
540+ let temp = ( ( self . iterations [ i] as f32 + self . smooth [ i] ) / self . iteration_division ) + self . iteration_offset ;
526541
527542 let temp2 = temp. floor ( ) as usize % self . palette . len ( ) ;
528543 let temp3 = ( temp as usize + 1 ) % self . palette . len ( ) ;
0 commit comments