// File: /workspace/github_cpp_makefile_star2_O3/rishabh-battulwar[P]imageprocessing/./include/ImageProc.h
// Function: ImageProc::denoising(char const*, char const*, int, int, int, int, float)
void ImageProc::denoising(const char *infile, const char *outfile, int width, int height, int window_size, int sigma, float threshold)
{
	Image img_orig("color", width, height);
	Image img_result("color", width, height);
	Image img_Lena("color", width, height);

	img_orig.read_image(infile, img_orig.cols, img_orig.rows);
	img_Lena.read_image("Lena.raw", img_Lena.cols, img_Lena.rows);

	//Separate channels
	Image img_red("bw", img_orig.cols, img_orig.rows);
	Image img_blue("bw", img_orig.cols, img_orig.rows);
	Image img_green("bw", img_orig.cols, img_orig.rows);
	Image img_redOut("bw", img_orig.cols, img_orig.rows);
	Image img_greenOut("bw", img_orig.cols, img_orig.rows);
	Image img_blueOut("bw", img_orig.cols, img_orig.rows);

	Image img_LenaR("bw", img_Lena.cols, img_Lena.rows);
	Image img_LenaB("bw", img_Lena.cols, img_Lena.rows);
	Image img_LenaG("bw", img_Lena.cols, img_Lena.rows);

	for(int i = 0; i < img_orig.rows; i++)
		for(int j = 0; j < img_orig.cols; j++)
		{
			img_red.setvalue(i,j,0,img_orig.getvalue(i,j,0));
			img_green.setvalue(i,j,0,img_orig.getvalue(i,j,1));
			img_blue.setvalue(i,j,0,img_orig.getvalue(i,j,2));
		}

	for(int i = 0; i < img_orig.rows; i++)
		for(int j = 0; j < img_orig.cols; j++)
		{
			img_LenaR.setvalue(i,j,0,img_Lena.getvalue(i,j,0));
			img_LenaG.setvalue(i,j,0,img_Lena.getvalue(i,j,1));
			img_LenaB.setvalue(i,j,0,img_Lena.getvalue(i,j,2));
		}

	median_filter(img_red, img_redOut, window_size);
	median_filter(img_green, img_greenOut, window_size);
	median_filter(img_blue, img_blueOut, window_size);

	for(int i = 0; i < img_orig.rows; i++)
		for(int j = 0; j < img_orig.cols; j++)
		{
			img_red.setvalue(i,j,0,img_redOut.getvalue(i,j,0));
			//img_green.setvalue(i,j,0,img_greenOut.getvalue(i,j,0));
			img_blue.setvalue(i,j,0,img_blueOut.getvalue(i,j,0));
		}

	gaussian_filter(img_red, img_redOut, window_size, sigma);
	//gaussian_filter(img_green, img_greenOut, window_size, sigma);
	gaussian_filter(img_blue, img_blueOut, window_size, sigma);

	float PSNR_red   = get_PSNR(img_red, img_redOut);
	float PSNR_green = get_PSNR(img_green, img_greenOut);
	float PSNR_blue  = get_PSNR(img_blue, img_blueOut);

	float PSNR_LenaR   = get_PSNR(img_LenaR, img_redOut);
	float PSNR_LenaG   = get_PSNR(img_LenaG, img_greenOut);
	float PSNR_LenaB   = get_PSNR(img_LenaB, img_blueOut);

	std::cout << "PSNR_red : " << PSNR_red << "\nPSNR_green : " << PSNR_green\
			<< "\nPSNR_blue : " << PSNR_blue << "\nPSNR_LenaR : " << PSNR_LenaR << "\nPSNR_LenaG: " << PSNR_LenaG\
			<< "\nPSNR_LenaB : " << PSNR_LenaB << std::endl;
	// hist_equal_proc(img_red, img_red_O);
	// hist_equal_proc(img_blue, img_blue_O);
	// hist_equal_proc(img_green, img_green_O);

	for(int i = 0; i < img_orig.rows; i++)
		for(int j = 0; j < img_orig.cols; j++)
		{
			img_result.setvalue(i,j,0,img_redOut.getvalue(i,j,0));
			img_result.setvalue(i,j,1,img_greenOut.getvalue(i,j,0));
			img_result.setvalue(i,j,2,img_blueOut.getvalue(i,j,0));
		}

	img_result.write_image(outfile, img_result.cols, img_result.rows);

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1d8, %rsp            # imm = 0x1D8
movl %r9d, 0x4c(%rsp)
movl %r8d, 0x44(%rsp)
movl %ecx, %ebp
movl %edx, %r14d
movq %rsi, 0xd0(%rsp)
movq %rdi, %r13
leaq 0x94dc(%rip), %r15      # 0x116c8
leaq 0x1b8(%rsp), %r12
movq %r12, %rdi
movq %r15, %rsi
callq 0x4c56
leaq 0x178(%rsp), %rdi
movq %r15, %rsi
movl %r14d, %edx
movl %ebp, %ecx
callq 0x4c56
leaq 0x198(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
movl %r14d, %edx
movl %ebp, %ecx
callq 0x4c56
movl 0x8(%r12), %r14d
movslq 0xc(%r12), %r15
movq %r12, %rdi
movq %r13, %rsi
callq 0x4cb2
movl 0x8(%rbx), %r13d
movl 0xc(%rbx), %ebp
leaq 0x94d3(%rip), %rsi      # 0x11722
movq %rbx, %rdi
callq 0x4cb2
leaq 0x9ff5(%rip), %r12      # 0x12253
leaq 0xb0(%rsp), %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %r15d, %ecx
callq 0x4c56
leaq 0x90(%rsp), %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %r15d, %ecx
callq 0x4c56
leaq 0xf8(%rsp), %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %r15d, %ecx
callq 0x4c56
leaq 0x70(%rsp), %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %r15d, %ecx
callq 0x4c56
leaq 0xd8(%rsp), %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %r15d, %ecx
callq 0x4c56
leaq 0x50(%rsp), %rdi
movq %r12, %rsi
movq %r14, 0x38(%rsp)
movl %r14d, %edx
movl %r15d, %ecx
callq 0x4c56
leaq 0x158(%rsp), %rdi
movq %r12, %rsi
movl %r13d, %edx
movl %ebp, %ecx
callq 0x4c56
leaq 0x138(%rsp), %rdi
movq %r12, %rsi
movl %r13d, %edx
movl %ebp, %ecx
callq 0x4c56
leaq 0x118(%rsp), %rdi
movq %r12, %rsi
movl %r13d, 0x48(%rsp)
movl %r13d, %edx
movl %ebp, %ecx
callq 0x4c56
movq %r15, 0x30(%rsp)
testq %r15, %r15
jle 0x86ee
movq 0x1d0(%rsp), %rax
movl 0x1c8(%rsp), %ecx
movq 0xc8(%rsp), %rdx
movl 0xc0(%rsp), %esi
movq 0x110(%rsp), %rdi
movl 0x108(%rsp), %r8d
movq 0xa8(%rsp), %r9
movl 0xa0(%rsp), %r10d
movq 0x38(%rsp), %r11
imull %ecx, %r11d
movl %r11d, (%rsp)
movl 0x98(%rsp), %r11d
imull %r10d, %r11d
movl %r11d, 0x14(%rsp)
movl 0x100(%rsp), %r11d
imull %r8d, %r11d
movl %r11d, 0x10(%rsp)
movl 0xb8(%rsp), %r11d
imull %esi, %r11d
movl %r11d, 0x24(%rsp)
xorl %r13d, %r13d
xorl %r14d, %r14d
xorl %r15d, %r15d
xorl %r11d, %r11d
xorl %ebx, %ebx
movq %rbx, 0x28(%rsp)
movq 0x38(%rsp), %rbx
movq %rbx, %rbp
movq %r13, 0x18(%rsp)
movl %r14d, 0xc(%rsp)
movl %r14d, %r12d
movl %r15d, 0x8(%rsp)
movl %r11d, 0x4(%rsp)
movl %r11d, %r14d
testl %ebx, %ebx
jle 0x8421
movslq %r14d, %r14
movb (%rax,%r14), %r11b
movslq %r13d, %r13
movb %r11b, (%rdx,%r13)
movb 0x1(%rax,%r14), %r11b
movslq %r12d, %r12
movb %r11b, (%rdi,%r12)
movb 0x2(%rax,%r14), %r11b
movslq %r15d, %r15
movb %r11b, (%r9,%r15)
addl %ecx, %r14d
addl %r10d, %r15d
addl %r8d, %r12d
addl %esi, %r13d
decq %rbp
jne 0x83ea
movq 0x28(%rsp), %rbx
incq %rbx
movl 0x4(%rsp), %r11d
addl (%rsp), %r11d
movl 0x8(%rsp), %r15d
addl 0x14(%rsp), %r15d
movl 0xc(%rsp), %r14d
addl 0x10(%rsp), %r14d
movq 0x18(%rsp), %r13
addl 0x24(%rsp), %r13d
cmpq 0x30(%rsp), %rbx
jne 0x83bf
cmpl $0x0, 0x30(%rsp)
jle 0x86ee
movq 0x1b0(%rsp), %rax
movl 0x1a8(%rsp), %ecx
movq 0x170(%rsp), %rdx
movl 0x168(%rsp), %esi
movq 0x130(%rsp), %rdi
movl 0x128(%rsp), %r8d
movq 0x150(%rsp), %r9
movl 0x148(%rsp), %r10d
movl 0x140(%rsp), %r11d
imull %r10d, %r11d
movl %r11d, (%rsp)
movl 0x120(%rsp), %r11d
imull %r8d, %r11d
movl %r11d, 0x14(%rsp)
movl 0x160(%rsp), %r11d
imull %esi, %r11d
movl %r11d, 0x10(%rsp)
movl 0x48(%rsp), %r11d
imull %ecx, %r11d
movl %r11d, 0x48(%rsp)
xorl %ebp, %ebp
xorl %r14d, %r14d
xorl %r15d, %r15d
xorl %ebx, %ebx
xorl %r11d, %r11d
movl %r11d, 0x28(%rsp)
movq 0x38(%rsp), %r13
movl %ebx, %r11d
movq %r13, %rbx
movl %ebp, 0x18(%rsp)
movl %r14d, 0xc(%rsp)
movl %r14d, %r12d
movl %r15d, 0x8(%rsp)
movl %r11d, 0x4(%rsp)
movl %r11d, %r14d
testl %r13d, %r13d
jle 0x8555
movslq %ebp, %rbp
movb (%rax,%rbp), %r13b
movslq %r12d, %r12
movb %r13b, (%rdx,%r12)
movb 0x1(%rax,%rbp), %r13b
movslq %r15d, %r15
movb %r13b, (%rdi,%r15)
movb 0x2(%rax,%rbp), %r13b
movslq %r14d, %r14
movb %r13b, (%r9,%r14)
addl %r10d, %r14d
addl %r8d, %r15d
addl %esi, %r12d
addl %ecx, %ebp
decq %rbx
jne 0x851f
movl 0x28(%rsp), %r11d
incl %r11d
movl 0x4(%rsp), %ebx
addl (%rsp), %ebx
movl 0x8(%rsp), %r15d
addl 0x14(%rsp), %r15d
movl 0xc(%rsp), %r14d
addl 0x10(%rsp), %r14d
movl 0x18(%rsp), %ebp
addl 0x48(%rsp), %ebp
cmpl 0x30(%rsp), %r11d
jne 0x84f1
leaq 0xb0(%rsp), %rdi
leaq 0x70(%rsp), %rsi
movl 0x44(%rsp), %ebx
movl %ebx, %edx
callq 0x8b40
leaq 0xf8(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
movl %ebx, %edx
callq 0x8b40
leaq 0x90(%rsp), %rdi
leaq 0x50(%rsp), %rsi
movl %ebx, %edx
callq 0x8b40
cmpl $0x0, 0x30(%rsp)
jle 0x8731
movq 0x88(%rsp), %rax
movl 0x80(%rsp), %ecx
movq 0xc8(%rsp), %rdx
movl 0xc0(%rsp), %esi
movq 0x68(%rsp), %rdi
movl 0x60(%rsp), %r8d
movq 0xa8(%rsp), %r9
movl 0xa0(%rsp), %r10d
movl 0x98(%rsp), %r11d
imull %r10d, %r11d
movl %r11d, (%rsp)
movl 0x58(%rsp), %r11d
imull %r8d, %r11d
movl %r11d, 0x14(%rsp)
movl 0xb8(%rsp), %r11d
imull %esi, %r11d
movl %r11d, 0x10(%rsp)
movl 0x78(%rsp), %r11d
imull %ecx, %r11d
movl %r11d, 0x24(%rsp)
xorl %r14d, %r14d
xorl %r15d, %r15d
xorl %r11d, %r11d
xorl %ebx, %ebx
xorl %ebp, %ebp
movl %ebp, 0x28(%rsp)
movq 0x38(%rsp), %rbp
movl %r14d, 0x18(%rsp)
movl %r14d, %r12d
movl %r15d, 0xc(%rsp)
movl %r15d, %r13d
movl %r11d, 0x8(%rsp)
movl %r11d, %r14d
movl %ebx, 0x4(%rsp)
movl %ebx, %r15d
cmpl $0x0, 0x38(%rsp)
jle 0x86b7
movslq %r12d, %r12
movb (%rax,%r12), %r11b
movslq %r13d, %r13
movb %r11b, (%rdx,%r13)
movslq %r14d, %r14
movb (%rdi,%r14), %r11b
movslq %r15d, %r15
movb %r11b, (%r9,%r15)
addl %r10d, %r15d
addl %r8d, %r14d
addl %esi, %r13d
addl %ecx, %r12d
decq %rbp
jne 0x868a
movl 0x28(%rsp), %ebp
incl %ebp
movl 0x4(%rsp), %ebx
addl (%rsp), %ebx
movl 0x8(%rsp), %r11d
addl 0x14(%rsp), %r11d
movl 0xc(%rsp), %r15d
addl 0x10(%rsp), %r15d
movl 0x18(%rsp), %r14d
addl 0x24(%rsp), %r14d
cmpl 0x30(%rsp), %ebp
jne 0x865b
jmp 0x8731
leaq 0xb0(%rsp), %rdi
leaq 0x70(%rsp), %rsi
movl 0x44(%rsp), %ebx
movl %ebx, %edx
callq 0x8b40
leaq 0xf8(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
movl %ebx, %edx
callq 0x8b40
leaq 0x90(%rsp), %rdi
leaq 0x50(%rsp), %rsi
movl %ebx, %edx
callq 0x8b40
cvtsi2ssl 0x4c(%rsp), %xmm0
movss %xmm0, 0x18(%rsp)
leaq 0xb0(%rsp), %r13
leaq 0x70(%rsp), %rbx
movq %r13, %rdi
movq %rbx, %rsi
movl 0x44(%rsp), %r14d
movl %r14d, %edx
callq 0x8de0
leaq 0x90(%rsp), %rbp
leaq 0x50(%rsp), %r12
movq %rbp, %rdi
movq %r12, %rsi
movl %r14d, %edx
movss 0x18(%rsp), %xmm0
callq 0x8de0
movq %r13, %rdi
movq %rbx, %rsi
callq 0x9940
cvtss2sd %xmm0, %xmm1
movsd 0x8d23(%rip), %xmm0     # 0x114b8
divsd %xmm1, %xmm0
callq 0x20b0
mulsd 0x8d1a(%rip), %xmm0     # 0x114c0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x18(%rsp)
leaq 0xf8(%rsp), %rdi
leaq 0xd8(%rsp), %r13
movq %r13, %rsi
callq 0x9940
xorps %xmm1, %xmm1
cvtss2sd %xmm0, %xmm1
movsd 0x8ce1(%rip), %xmm0     # 0x114b8
divsd %xmm1, %xmm0
callq 0x20b0
mulsd 0x8cd8(%rip), %xmm0     # 0x114c0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0xc(%rsp)
movq %rbp, %rdi
movq %r12, %rsi
callq 0x9940
xorps %xmm1, %xmm1
cvtss2sd %xmm0, %xmm1
movsd 0x8cac(%rip), %xmm0     # 0x114b8
divsd %xmm1, %xmm0
callq 0x20b0
mulsd 0x8ca3(%rip), %xmm0     # 0x114c0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x8(%rsp)
leaq 0x158(%rsp), %rdi
movq %rbx, %rsi
callq 0x9940
xorps %xmm1, %xmm1
cvtss2sd %xmm0, %xmm1
movsd 0x8c72(%rip), %xmm0     # 0x114b8
divsd %xmm1, %xmm0
callq 0x20b0
mulsd 0x8c69(%rip), %xmm0     # 0x114c0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x4(%rsp)
leaq 0x118(%rsp), %rdi
movq %r13, %rsi
callq 0x9940
xorps %xmm1, %xmm1
cvtss2sd %xmm0, %xmm1
movsd 0x8c38(%rip), %xmm0     # 0x114b8
divsd %xmm1, %xmm0
callq 0x20b0
mulsd 0x8c2f(%rip), %xmm0     # 0x114c0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x28(%rsp)
leaq 0x138(%rsp), %rdi
movq %r12, %rsi
callq 0x9940
xorps %xmm1, %xmm1
cvtss2sd %xmm0, %xmm1
movsd 0x8bfe(%rip), %xmm0     # 0x114b8
divsd %xmm1, %xmm0
callq 0x20b0
mulsd 0x8bf5(%rip), %xmm0     # 0x114c0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, (%rsp)
movq 0xd6f5(%rip), %rbx      # 0x15fd0
leaq 0x8e49(%rip), %rsi      # 0x1172b
movl $0xb, %edx
movq %rbx, %rdi
callq 0x21a0
xorps %xmm0, %xmm0
cvtss2sd 0x18(%rsp), %xmm0
movq %rbx, %rdi
callq 0x2250
movq %rax, %rbx
leaq 0x8e2d(%rip), %rsi      # 0x11737
movl $0xe, %edx
movq %rax, %rdi
callq 0x21a0
xorps %xmm0, %xmm0
cvtss2sd 0xc(%rsp), %xmm0
movq %rbx, %rdi
callq 0x2250
movq %rax, %rbx
leaq 0x8e14(%rip), %rsi      # 0x11746
movl $0xd, %edx
movq %rax, %rdi
callq 0x21a0
xorps %xmm0, %xmm0
cvtss2sd 0x8(%rsp), %xmm0
movq %rbx, %rdi
callq 0x2250
movq %rax, %rbx
leaq 0x8dfa(%rip), %rsi      # 0x11754
movl $0xe, %edx
movq %rax, %rdi
callq 0x21a0
xorps %xmm0, %xmm0
cvtss2sd 0x4(%rsp), %xmm0
movq %rbx, %rdi
callq 0x2250
movq %rax, %rbx
leaq 0x8de1(%rip), %rsi      # 0x11763
movl $0xd, %edx
movq %rax, %rdi
callq 0x21a0
xorps %xmm0, %xmm0
cvtss2sd 0x28(%rsp), %xmm0
movq %rbx, %rdi
callq 0x2250
movq %rax, %rbx
leaq 0x8dc7(%rip), %rsi      # 0x11771
movl $0xe, %edx
movq %rax, %rdi
callq 0x21a0
xorps %xmm0, %xmm0
cvtss2sd (%rsp), %xmm0
movq %rbx, %rdi
callq 0x2250
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2150
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20d0
cmpl $0x0, 0x30(%rsp)
jle 0x8b19
movq 0x88(%rsp), %rax
movl 0x80(%rsp), %ecx
movq 0x190(%rsp), %rdx
movl 0x188(%rsp), %esi
movq 0xf0(%rsp), %rdi
movl 0xe8(%rsp), %r8d
movq 0x68(%rsp), %r9
movl 0x60(%rsp), %r10d
movl 0x58(%rsp), %r11d
imull %r10d, %r11d
movl %r11d, (%rsp)
movl 0xe0(%rsp), %r11d
imull %r8d, %r11d
movl %r11d, 0x14(%rsp)
movl 0x180(%rsp), %r11d
imull %esi, %r11d
movl %r11d, 0x10(%rsp)
movl 0x78(%rsp), %r11d
imull %ecx, %r11d
movl %r11d, 0x24(%rsp)
xorl %r14d, %r14d
xorl %r15d, %r15d
xorl %r11d, %r11d
xorl %ebx, %ebx
xorl %ebp, %ebp
movl %ebp, 0x28(%rsp)
movq 0x38(%rsp), %rbp
movl %r14d, 0x18(%rsp)
movl %r14d, %r12d
movl %r15d, 0xc(%rsp)
movl %r15d, %r13d
movl %r11d, 0x8(%rsp)
movl %r11d, %r15d
movl %ebx, 0x4(%rsp)
movl %ebx, %r14d
cmpl $0x0, 0x38(%rsp)
jle 0x8ae4
movslq %r12d, %r12
movb (%rax,%r12), %r11b
movslq %r13d, %r13
movb %r11b, (%rdx,%r13)
movslq %r15d, %r15
movb (%rdi,%r15), %r11b
movb %r11b, 0x1(%rdx,%r13)
movslq %r14d, %r14
movb (%r9,%r14), %r11b
movb %r11b, 0x2(%rdx,%r13)
addl %r10d, %r14d
addl %r8d, %r15d
addl %esi, %r13d
addl %ecx, %r12d
decq %rbp
jne 0x8aad
movl 0x28(%rsp), %ebp
incl %ebp
movl 0x4(%rsp), %ebx
addl (%rsp), %ebx
movl 0x8(%rsp), %r11d
addl 0x14(%rsp), %r11d
movl 0xc(%rsp), %r15d
addl 0x10(%rsp), %r15d
movl 0x18(%rsp), %r14d
addl 0x24(%rsp), %r14d
cmpl 0x30(%rsp), %ebp
jne 0x8a7e
leaq 0x178(%rsp), %rdi
movq 0xd0(%rsp), %rsi
callq 0x4dee
addq $0x1d8, %rsp            # imm = 0x1D8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq