// File: /workspace/github_cpp_makefile_star2_O1/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, 0x48(%rsp)
movl %r8d, 0x44(%rsp)
movl %ecx, %ebp
movl %edx, %r14d
movq %rsi, 0xd0(%rsp)
movq %rdi, %r13
leaq 0x952c(%rip), %r15      # 0x1165c
leaq 0x1b8(%rsp), %r12
movq %r12, %rdi
movq %r15, %rsi
callq 0x4c6e
leaq 0x178(%rsp), %rdi
movq %r15, %rsi
movl %r14d, %edx
movl %ebp, %ecx
callq 0x4c6e
leaq 0x198(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
movl %r14d, %edx
movl %ebp, %ecx
callq 0x4c6e
movl 0x8(%r12), %r14d
movslq 0xc(%r12), %r15
movq %r12, %rdi
movq %r13, %rsi
callq 0x4cde
movl 0x8(%rbx), %r13d
movl 0xc(%rbx), %ebp
leaq 0x9523(%rip), %rsi      # 0x116b6
movq %rbx, %rdi
callq 0x4cde
leaq 0xa045(%rip), %r12      # 0x121e7
leaq 0xb0(%rsp), %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %r15d, %ecx
callq 0x4c6e
leaq 0x90(%rsp), %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %r15d, %ecx
callq 0x4c6e
leaq 0xf8(%rsp), %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %r15d, %ecx
callq 0x4c6e
leaq 0x70(%rsp), %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %r15d, %ecx
callq 0x4c6e
leaq 0xd8(%rsp), %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %r15d, %ecx
callq 0x4c6e
leaq 0x50(%rsp), %rdi
movq %r12, %rsi
movq %r14, 0x38(%rsp)
movl %r14d, %edx
movl %r15d, %ecx
callq 0x4c6e
leaq 0x158(%rsp), %rdi
movq %r12, %rsi
movl %r13d, %edx
movl %ebp, %ecx
callq 0x4c6e
leaq 0x138(%rsp), %rdi
movq %r12, %rsi
movl %r13d, %edx
movl %ebp, %ecx
callq 0x4c6e
leaq 0x118(%rsp), %rdi
movq %r12, %rsi
movl %r13d, 0x4(%rsp)
movl %r13d, %edx
movl %ebp, %ecx
callq 0x4c6e
movq %r15, 0x30(%rsp)
testq %r15, %r15
jle 0x839e
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, 0x1c(%rsp)
movl 0xb8(%rsp), %r11d
imull %esi, %r11d
movl %r11d, 0x18(%rsp)
movl 0x100(%rsp), %r11d
imull %r8d, %r11d
movl %r11d, 0x14(%rsp)
movl 0x98(%rsp), %r11d
imull %r10d, %r11d
movl %r11d, 0x4c(%rsp)
xorl %r13d, %r13d
xorl %r11d, %r11d
xorl %r15d, %r15d
xorl %ebx, %ebx
xorl %r14d, %r14d
movq 0x38(%rsp), %rbp
movq %r14, 0x28(%rsp)
movq %rbp, %r14
movq %r13, 0x20(%rsp)
movl %r11d, 0x10(%rsp)
movl %r11d, %r12d
movl %r15d, 0xc(%rsp)
movl %ebx, 0x8(%rsp)
movl %ebx, %r11d
testl %ebp, %ebp
jle 0x8365
movslq %r11d, %r11
movb (%rax,%r11), %bl
movslq %r15d, %r15
movb %bl, (%rdx,%r15)
movb 0x1(%rax,%r11), %bl
movslq %r12d, %r12
movb %bl, (%rdi,%r12)
movb 0x2(%rax,%r11), %bl
movslq %r13d, %r13
movb %bl, (%r9,%r13)
addl %ecx, %r11d
addl %esi, %r15d
addl %r8d, %r12d
addl %r10d, %r13d
decq %r14
jne 0x832e
movq 0x28(%rsp), %r14
incq %r14
movl 0x8(%rsp), %ebx
addl 0x1c(%rsp), %ebx
movl 0xc(%rsp), %r15d
addl 0x18(%rsp), %r15d
movl 0x10(%rsp), %r11d
addl 0x14(%rsp), %r11d
movq 0x20(%rsp), %r13
addl 0x4c(%rsp), %r13d
cmpq 0x30(%rsp), %r14
jne 0x8309
cmpl $0x0, 0x30(%rsp)
jle 0x84ce
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 0x4(%rsp), %r11d
imull %ecx, %r11d
movl %r11d, 0x4(%rsp)
movl 0x160(%rsp), %r11d
imull %esi, %r11d
movl %r11d, 0x1c(%rsp)
movl 0x120(%rsp), %r11d
imull %r8d, %r11d
movl %r11d, 0x18(%rsp)
movl 0x140(%rsp), %r11d
imull %r10d, %r11d
movl %r11d, 0x14(%rsp)
xorl %ebp, %ebp
xorl %r15d, %r15d
xorl %r13d, %r13d
xorl %r11d, %r11d
xorl %ebx, %ebx
movl %ebx, 0x28(%rsp)
movq 0x38(%rsp), %rbx
movq %rbx, %r14
movl %ebp, 0x20(%rsp)
movl %r15d, 0x10(%rsp)
movl %r15d, %r12d
movl %r13d, 0xc(%rsp)
movl %r13d, %r15d
movl %r11d, 0x8(%rsp)
movl %r11d, %r13d
testl %ebx, %ebx
jle 0x8498
movslq %r13d, %r13
movb (%rax,%r13), %r11b
movslq %r15d, %r15
movb %r11b, (%rdx,%r15)
movb 0x1(%rax,%r13), %r11b
movslq %r12d, %r12
movb %r11b, (%rdi,%r12)
movb 0x2(%rax,%r13), %r11b
movslq %ebp, %rbp
movb %r11b, (%r9,%rbp)
addl %ecx, %r13d
addl %esi, %r15d
addl %r8d, %r12d
addl %r10d, %ebp
decq %r14
jne 0x8461
movl 0x28(%rsp), %ebx
incl %ebx
movl 0x8(%rsp), %r11d
addl 0x4(%rsp), %r11d
movl 0xc(%rsp), %r13d
addl 0x1c(%rsp), %r13d
movl 0x10(%rsp), %r15d
addl 0x18(%rsp), %r15d
movl 0x20(%rsp), %ebp
addl 0x14(%rsp), %ebp
cmpl 0x30(%rsp), %ebx
jne 0x8435
leaq 0xb0(%rsp), %rdi
leaq 0x70(%rsp), %rsi
movl 0x44(%rsp), %ebx
movl %ebx, %edx
callq 0x8a46
leaq 0xf8(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
movl %ebx, %edx
callq 0x8a46
leaq 0x90(%rsp), %rdi
leaq 0x50(%rsp), %rsi
movl %ebx, %edx
callq 0x8a46
cmpl $0x0, 0x30(%rsp)
jle 0x8632
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 0x78(%rsp), %r11d
imull %ecx, %r11d
movl %r11d, 0x4(%rsp)
movl 0xb8(%rsp), %r11d
imull %esi, %r11d
movl %r11d, 0x1c(%rsp)
movl 0x58(%rsp), %r11d
imull %r8d, %r11d
movl %r11d, 0x18(%rsp)
movl 0x98(%rsp), %r11d
imull %r10d, %r11d
movl %r11d, 0x14(%rsp)
xorl %r11d, %r11d
xorl %r15d, %r15d
xorl %ebx, %ebx
xorl %ebp, %ebp
xorl %r14d, %r14d
movl %r14d, 0x28(%rsp)
movq 0x38(%rsp), %r14
movl %r11d, 0x20(%rsp)
movl %r11d, %r12d
movl %r15d, 0x10(%rsp)
movl %r15d, %r13d
movl %ebx, 0xc(%rsp)
movl %ebx, %r15d
movl %ebp, 0x8(%rsp)
movl %ebp, %r11d
cmpl $0x0, 0x38(%rsp)
jle 0x85fb
movslq %r11d, %r11
movb (%rax,%r11), %bl
movslq %r15d, %r15
movb %bl, (%rdx,%r15)
movslq %r13d, %r13
movb (%rdi,%r13), %bl
movslq %r12d, %r12
movb %bl, (%r9,%r12)
addl %ecx, %r11d
addl %esi, %r15d
addl %r8d, %r13d
addl %r10d, %r12d
decq %r14
jne 0x85ce
movl 0x28(%rsp), %r14d
incl %r14d
movl 0x8(%rsp), %ebp
addl 0x4(%rsp), %ebp
movl 0xc(%rsp), %ebx
addl 0x1c(%rsp), %ebx
movl 0x10(%rsp), %r15d
addl 0x18(%rsp), %r15d
movl 0x20(%rsp), %r11d
addl 0x14(%rsp), %r11d
cmpl 0x30(%rsp), %r14d
jne 0x859f
cvtsi2ssl 0x48(%rsp), %xmm0
movss %xmm0, 0x20(%rsp)
leaq 0xb0(%rsp), %r13
leaq 0x70(%rsp), %rbx
movq %r13, %rdi
movq %rbx, %rsi
movl 0x44(%rsp), %r14d
movl %r14d, %edx
callq 0x8ce4
leaq 0x90(%rsp), %rbp
leaq 0x50(%rsp), %r12
movq %rbp, %rdi
movq %r12, %rsi
movl %r14d, %edx
movss 0x20(%rsp), %xmm0
callq 0x8ce4
movq %r13, %rdi
movq %rbx, %rsi
callq 0x98b2
cvtss2sd %xmm0, %xmm1
movsd 0x8e82(%rip), %xmm0     # 0x11518
divsd %xmm1, %xmm0
callq 0x20b0
mulsd 0x8e79(%rip), %xmm0     # 0x11520
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x20(%rsp)
leaq 0xf8(%rsp), %rdi
leaq 0xd8(%rsp), %r13
movq %r13, %rsi
callq 0x98b2
xorps %xmm1, %xmm1
cvtss2sd %xmm0, %xmm1
movsd 0x8e40(%rip), %xmm0     # 0x11518
divsd %xmm1, %xmm0
callq 0x20b0
mulsd 0x8e37(%rip), %xmm0     # 0x11520
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x10(%rsp)
movq %rbp, %rdi
movq %r12, %rsi
callq 0x98b2
xorps %xmm1, %xmm1
cvtss2sd %xmm0, %xmm1
movsd 0x8e0b(%rip), %xmm0     # 0x11518
divsd %xmm1, %xmm0
callq 0x20b0
mulsd 0x8e02(%rip), %xmm0     # 0x11520
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0xc(%rsp)
leaq 0x158(%rsp), %rdi
movq %rbx, %rsi
callq 0x98b2
xorps %xmm1, %xmm1
cvtss2sd %xmm0, %xmm1
movsd 0x8dd1(%rip), %xmm0     # 0x11518
divsd %xmm1, %xmm0
callq 0x20b0
mulsd 0x8dc8(%rip), %xmm0     # 0x11520
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x8(%rsp)
leaq 0x118(%rsp), %rdi
movq %r13, %rsi
callq 0x98b2
xorps %xmm1, %xmm1
cvtss2sd %xmm0, %xmm1
movsd 0x8d97(%rip), %xmm0     # 0x11518
divsd %xmm1, %xmm0
callq 0x20b0
mulsd 0x8d8e(%rip), %xmm0     # 0x11520
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x28(%rsp)
leaq 0x138(%rsp), %rdi
movq %r12, %rsi
callq 0x98b2
xorps %xmm1, %xmm1
cvtss2sd %xmm0, %xmm1
movsd 0x8d5d(%rip), %xmm0     # 0x11518
divsd %xmm1, %xmm0
callq 0x20b0
mulsd 0x8d54(%rip), %xmm0     # 0x11520
cvtsd2ss %xmm0, %xmm0
movss %xmm0, 0x4(%rsp)
movq 0xd7f3(%rip), %rbx      # 0x15fd0
leaq 0x8edb(%rip), %rsi      # 0x116bf
movl $0xb, %edx
movq %rbx, %rdi
callq 0x21b0
xorps %xmm0, %xmm0
cvtss2sd 0x20(%rsp), %xmm0
movq %rbx, %rdi
callq 0x2260
movq %rax, %rbx
leaq 0x8ebf(%rip), %rsi      # 0x116cb
movl $0xe, %edx
movq %rax, %rdi
callq 0x21b0
xorps %xmm0, %xmm0
cvtss2sd 0x10(%rsp), %xmm0
movq %rbx, %rdi
callq 0x2260
movq %rax, %rbx
leaq 0x8ea6(%rip), %rsi      # 0x116da
movl $0xd, %edx
movq %rax, %rdi
callq 0x21b0
xorps %xmm0, %xmm0
cvtss2sd 0xc(%rsp), %xmm0
movq %rbx, %rdi
callq 0x2260
movq %rax, %rbx
leaq 0x8e8c(%rip), %rsi      # 0x116e8
movl $0xe, %edx
movq %rax, %rdi
callq 0x21b0
xorps %xmm0, %xmm0
cvtss2sd 0x8(%rsp), %xmm0
movq %rbx, %rdi
callq 0x2260
movq %rax, %rbx
leaq 0x8e73(%rip), %rsi      # 0x116f7
movl $0xd, %edx
movq %rax, %rdi
callq 0x21b0
xorps %xmm0, %xmm0
cvtss2sd 0x28(%rsp), %xmm0
movq %rbx, %rdi
callq 0x2260
movq %rax, %rbx
leaq 0x8e59(%rip), %rsi      # 0x11705
movl $0xe, %edx
movq %rax, %rdi
callq 0x21b0
xorps %xmm0, %xmm0
cvtss2sd 0x4(%rsp), %xmm0
movq %rbx, %rdi
callq 0x2260
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2160
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20d0
cmpl $0x0, 0x30(%rsp)
jle 0x8a1f
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 0x78(%rsp), %r11d
imull %ecx, %r11d
movl %r11d, 0x4(%rsp)
movl 0x180(%rsp), %r11d
imull %esi, %r11d
movl %r11d, 0x1c(%rsp)
movl 0xe0(%rsp), %r11d
imull %r8d, %r11d
movl %r11d, 0x18(%rsp)
movl 0x58(%rsp), %r11d
imull %r10d, %r11d
movl %r11d, 0x14(%rsp)
xorl %r11d, %r11d
xorl %r15d, %r15d
xorl %ebx, %ebx
xorl %ebp, %ebp
xorl %r14d, %r14d
movl %r14d, 0x28(%rsp)
movq 0x38(%rsp), %r14
movl %r11d, 0x20(%rsp)
movl %r11d, %r12d
movl %r15d, 0x10(%rsp)
movl %r15d, %r13d
movl %ebx, 0xc(%rsp)
movl %ebx, %r15d
movl %ebp, 0x8(%rsp)
movl %ebp, %r11d
cmpl $0x0, 0x38(%rsp)
jle 0x89e8
movslq %r11d, %r11
movb (%rax,%r11), %bl
movslq %r15d, %r15
movb %bl, (%rdx,%r15)
movslq %r13d, %r13
movb (%rdi,%r13), %bl
movb %bl, 0x1(%rdx,%r15)
movslq %r12d, %r12
movb (%r9,%r12), %bl
movb %bl, 0x2(%rdx,%r15)
addl %ecx, %r11d
addl %esi, %r15d
addl %r8d, %r13d
addl %r10d, %r12d
decq %r14
jne 0x89b1
movl 0x28(%rsp), %r14d
incl %r14d
movl 0x8(%rsp), %ebp
addl 0x4(%rsp), %ebp
movl 0xc(%rsp), %ebx
addl 0x1c(%rsp), %ebx
movl 0x10(%rsp), %r15d
addl 0x18(%rsp), %r15d
movl 0x20(%rsp), %r11d
addl 0x14(%rsp), %r11d
cmpl 0x30(%rsp), %r14d
jne 0x8982
leaq 0x178(%rsp), %rdi
movq 0xd0(%rsp), %rsi
callq 0x4e1a
addq $0x1d8, %rsp            # imm = 0x1D8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq