void RLDeconvolution()
{

	Image input, blur, deblur, temporary, gain;

	// Load
	gain.Name = "f:\\redqueen\\gain.bmp";
	gain.Load();
	input.Name = "f:\\redqueen\\image.pfm";
	input.Load();
	SInt32 w = input.Width;
	SInt32 h = input.Height;
	deblur.Create(input.Width, input.Height, input.SamplePerPixel, input.BitPerSample);
	temporary.Create(input.Width, input.Height, input.SamplePerPixel, input.BitPerSample);
	blur.Create(input.Width, input.Height, input.SamplePerPixel, input.BitPerSample);

	Colour color, convolve, weight;

	// Kernel, Whatever U Like
	const SInt32 kernel_size = 3;
	Real32       sum = 0.0f;
	Real32       kernel[kernel_size*2+1][kernel_size*2+1] = 
	{
			1,1,1,1,1,0,0,
			0,0,0,1,0,0,0,
			0,0,0,1,0,0,0,
			0,0,0,0,1,0,0,
			0,0,0,0,1,0,0,
			1,1,0,0,0,1,1,
			1,1,0,0,0,1,1,
	};

	// Normalize Kernel
	for(SInt32 y = -kernel_size; y <= kernel_size; ++y)
	{
		for(SInt32 x = -kernel_size; x <= kernel_size; ++x)
		{
			sum += kernel[y+kernel_size][x+kernel_size];
		}
	}
	for(SInt32 y = -kernel_size; y <= kernel_size; ++y)
	{
		for(SInt32 x = -kernel_size; x <= kernel_size; ++x)
		{
			kernel[y+kernel_size][x+kernel_size] /= sum;
		}
	}

	// Create Blured Image
	for(SInt32 v = 0; v < h; ++v)
	{
		for(SInt32 u = 0; u < w; ++u)
		{
			for(SInt32 y = -kernel_size; y <= kernel_size; ++y)
			{
				for(SInt32 x = -kernel_size; x <= kernel_size; ++x)
				{
					input.GetColor(color, u+x, v+y, Image::Addressing::Clamp, Image::Addressing::Clamp);
					color *= kernel[y+kernel_size][x+kernel_size];
					blur.AddColor(color, u, v);
				}
			}
		}
	}

	// Save Blured Image
	blur.Name = "f:\\redqueen\\blured.pfm";
	blur.Save();

	// 0th Image
	for(SInt32 v = 0; v < h; ++v)
	{
		for(SInt32 u = 0; u < w; ++u)
		{
			blur  .GetColor(color, u, v);
			deblur.SetColor(color, u, v);
		}
	}

	// Deconvolution
	for(SInt32 i = 0; i < 100; ++i)
	{
		for(SInt32 v = 0; v < h; ++v)
		{
			for(SInt32 u = 0; u < w; ++u)
			{
				// Convolution
				convolve = Black;
				for(SInt32 y = -kernel_size; y <= kernel_size; ++y)
				{
					for(SInt32 x = -kernel_size; x <= kernel_size; ++x)
					{
						deblur.GetColor(color, u+x, v+y, Image::Addressing::Clamp, Image::Addressing::Clamp);
						convolve += color * kernel[y+kernel_size][x+kernel_size];
					}
				}
				blur.GetColor(color, u, v);
				temporary.SetColor((color+White)/(convolve+White), u, v);
			}
		}
		for(SInt32 v = 0; v < h; ++v)
		{
			for(SInt32 u = 0; u < w; ++u)
			{
				// Correlation (#NOT Convolution)
				convolve = Black;
				for(SInt32 y = -kernel_size; y <= kernel_size; ++y)
				{
					for(SInt32 x = -kernel_size; x <= kernel_size; ++x)
					{
						temporary.GetColor(color, u-x, v-y, Image::Addressing::Clamp, Image::Addressing::Clamp);
						convolve += color * kernel[y+kernel_size][x+kernel_size];
					}
				}
				gain  .GetColor(weight, u, v);
				deblur.GetColor(color, u, v);
				deblur.SetColor(((color+White)*convolve) /** weight*/ - White, u, v);
			}
		}

		// Progress
		std::cout << "\r" << i+1 << " th iteration" << std::endl;

	}

	// Save DeBlured Image
	deblur.Name = "f:\\redqueen\\deblured.pfm";
	deblur.Save();

}
