var order = 2; 

var fimg = GetImage(0);  // get access to opened image

// create temporary image buffers
var src = new Image(fimg.Width, fimg.Height);
var temp = new Image(fimg.Width, fimg.Height);
var sh;

var coeff = new Array(3);
var theta;
var sintheta;
 
src.Copy(fimg);
fimg.Clear(0,0,0);

var diffcoef = new Array(3);
diffcoef[0] = 3.14159265358979323;
diffcoef[1] = 2.094395;
diffcoef[2] = 0.785398;

for (L = 0; L <= order; L++)
{
	for (M = -L; M <= L; M++)
	{
		sh = CreateSphericalHarmonic(M, L, fimg.Width, fimg.Height, 5); // 5 = Latitude-longitude

		temp.Copy(sh);
		temp.Mult(src);	// temp = dot product sh, src
		
		var coeff = new Array(3);
	    coeff[0] = 0.0;
		coeff[1] = 0.0;
		coeff[2] = 0.0;
    
    	for (y = 0; y < temp.Height; y++)
    	{
			theta = y * 3.14159265358979323 / temp.Height;
			sintheta = Math.sin( theta );

			// weight each line by sin(theta)
			for (x = 0; x < temp.Width; x++)
			{
				coeff[0] += temp.R(x,y) * sintheta;
				coeff[1] += temp.G(x,y) * sintheta;
				coeff[2] += temp.B(x,y) * sintheta;
			}
		}
		
		// dphi
 		coeff[0] *= 3.1415926535 / temp.Height;
 		coeff[1] *= 3.1415926535 / temp.Height;
 		coeff[2] *= 3.1415926535 / temp.Height;
 	
 		// dtheta
    	coeff[0] *= 2 * 3.1415926535 / temp.Width;
 		coeff[1] *= 2 * 3.1415926535 / temp.Width;
 		coeff[2] *= 2 * 3.1415926535 / temp.Width;
			
		sh.Scale(coeff[0] * diffcoef[L] / 3.14159265358979323, coeff[1] * diffcoef[L] / 3.14159265358979323, coeff[2] * diffcoef[L] / 3.14159265358979323);		// apply diffuse coefficients and scale SH image

		fimg.Add(sh);	// accumulate scaled SH
		
		sh.Close(1)
	}
}

temp.Close(1);
src.Close(1);
