@@ -446,42 +446,66 @@ void get_color_pixels_accumulate (uint16_t * mask,
446446 float * sum_r ,
447447 float * sum_g ,
448448 float * sum_b ,
449- float * sum_a
449+ float * sum_a ,
450+ float paint
450451 ) {
451452
452453
453- // The sum of a 64x64 tile fits into a 32 bit integer, but the sum
454- // of an arbitrary number of tiles may not fit. We assume that we
455- // are processing a single tile at a time, so we can use integers.
456- // But for the result we need floats.
454+ // Sample the canvas as additive and subtractive
455+ // According to paint parameter
456+ // Average the results normally
457+ // Only sample a random selection of pixels
457458
458- uint32_t weight = 0 ;
459- uint32_t r = 0 ;
460- uint32_t g = 0 ;
461- uint32_t b = 0 ;
462- uint32_t a = 0 ;
459+ float avg_spectral [ 10 ] = { 0 } ;
460+ float avg_rgb [ 3 ] = { * sum_r , * sum_g , * sum_b } ;
461+ if ( paint > 0.0f ) {
462+ rgb_to_spectral ( * sum_r , * sum_g , * sum_b , avg_spectral ) ;
463+ }
463464
464465 while (1 ) {
465466 for (; mask [0 ]; mask ++ , rgba += 4 ) {
466- uint32_t opa = mask [0 ];
467- weight += opa ;
468- r += opa * rgba [0 ]/(1 <<15 );
469- g += opa * rgba [1 ]/(1 <<15 );
470- b += opa * rgba [2 ]/(1 <<15 );
471- a += opa * rgba [3 ]/(1 <<15 );
472-
467+ // sample at least one pixel but then only 1%
468+ if (rand () % 100 != 0 && * sum_a > 0.0 ) {
469+ continue ;
470+ }
471+ float a = (float )mask [0 ] * rgba [3 ] / (1 <<30 );
472+ float alpha_sums = a + * sum_a ;
473+ * sum_weight += (float )mask [0 ] / (1 <<15 );
474+ float fac_a , fac_b ;
475+ fac_a = fac_b = 1.0f ;
476+ if (alpha_sums > 0.0f ) {
477+ fac_a = a / alpha_sums ;
478+ fac_b = 1.0 - fac_a ;
479+ }
480+ if (paint > 0.0f ) {
481+ float spectral [10 ] = {0 };
482+ if (rgba [3 ] > 0 ) {
483+ rgb_to_spectral ((float )rgba [0 ] / rgba [3 ], (float )rgba [1 ] / rgba [3 ], (float )rgba [2 ] / rgba [3 ], spectral );
484+ for (int i = 0 ; i < 10 ; i ++ ) {
485+ avg_spectral [i ] = fastpow (spectral [i ], fac_a ) * fastpow (avg_spectral [i ], fac_b );
486+ }
487+ }
488+ }
489+ if (paint < 1.0f ) {
490+ if (rgba [3 ] > 0 ) {
491+ for (int i = 0 ; i < 3 ; i ++ ) {
492+ avg_rgb [i ] = (float )rgba [i ] * fac_a / rgba [3 ] + (float )avg_rgb [i ] * fac_b ;
493+ }
494+ }
495+ }
496+ * sum_a += a ;
473497 }
498+ float spec_rgb [3 ] = {0 };
499+ spectral_to_rgb (avg_spectral , spec_rgb );
500+
501+ * sum_r = spec_rgb [0 ] * paint + (1.0 - paint ) * avg_rgb [0 ];
502+ * sum_g = spec_rgb [1 ] * paint + (1.0 - paint ) * avg_rgb [1 ];
503+ * sum_b = spec_rgb [2 ] * paint + (1.0 - paint ) * avg_rgb [2 ];
504+
474505 if (!mask [1 ]) break ;
475506 rgba += mask [1 ];
476507 mask += 2 ;
477508 }
478-
479- // convert integer to float outside the performance critical loop
480- * sum_weight += weight ;
481- * sum_r += r ;
482- * sum_g += g ;
483- * sum_b += b ;
484- * sum_a += a ;
485509};
486510
487511
0 commit comments