/** Weighted per-channel variance of the box. It's used to decide which channel to split by */ static f_pixel box_variance(const hist_item achv[], const box* box) { f_pixel mean = box->color; f_pixel variance(0.0, 0.0, 0.0, 0.0); f_pixel goodEnough(2.0/256.0, 1.0/256.0, 1.0/256.0, 1.0/256.0); goodEnough.square(); for (uint i=0; i<box->colors; ++i) { f_pixel px = achv[box->ind + i].acolor; double weight = achv[box->ind + i].adjusted_weight; f_pixel diff = mean - px; diff.square(); if (diff.alpha < goodEnough.alpha) diff.alpha *= 0.5; if (diff.r < goodEnough.r) diff.r *= 0.5; if (diff.g < goodEnough.g) diff.g *= 0.5; if (diff.b < goodEnough.b) diff.b *= 0.5; variance += diff * weight; } variance *= f_pixel(4.0/16.0, 7.0/16.0, 9.0/16.0, 5.0/16.0); return variance; }
static double sqrtIter(double x, double guess) { if(goodEnough(x, guess)) return guess; return sqrtIter(x, improveGuess(x, guess)); }