// File: /workspace/github_cpp_makefile_star2_O2/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 $0x1f8, %rsp            # imm = 0x1F8
movl %r9d, 0x60(%rsp)
movl %r8d, 0x54(%rsp)
movl %ecx, %ebp
movl %edx, %r14d
movq %rsi, 0x70(%rsp)
movq %rdi, %r15
leaq 0x96d3(%rip), %r12      # 0x106c8
leaq 0x1d8(%rsp), %rbx
movq %rbx, %rdi
movq %r12, %rsi
callq 0x3fd6
leaq 0xf8(%rsp), %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %ebp, %ecx
callq 0x3fd6
leaq 0x1b8(%rsp), %r13
movq %r13, %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %ebp, %ecx
callq 0x3fd6
movq %rbx, %rdi
movl 0x8(%rbx), %r14d
movl 0xc(%rbx), %ebx
movq %r15, %rsi
callq 0x4032
movl 0x8(%r13), %ebp
movl 0xc(%r13), %r15d
leaq 0x9b31(%rip), %rsi      # 0x10b87
movq %r13, %rdi
callq 0x4032
leaq 0xa64f(%rip), %r12      # 0x116b4
leaq 0x198(%rsp), %r13
movq %r13, %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %ebx, %ecx
callq 0x3fd6
leaq 0xd8(%rsp), %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %ebx, %ecx
callq 0x3fd6
leaq 0x118(%rsp), %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %ebx, %ecx
callq 0x3fd6
leaq 0x178(%rsp), %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %ebx, %ecx
callq 0x3fd6
leaq 0x158(%rsp), %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %ebx, %ecx
callq 0x3fd6
leaq 0x138(%rsp), %rdi
movq %r12, %rsi
movl %r14d, %edx
movl %ebx, %ecx
callq 0x3fd6
leaq 0xb8(%rsp), %rdi
movq %r12, %rsi
movl %ebp, %edx
movl %r15d, %ecx
callq 0x3fd6
leaq 0x98(%rsp), %rdi
movq %r12, %rsi
movl %ebp, %edx
movl %r15d, %ecx
callq 0x3fd6
leaq 0x78(%rsp), %rdi
movq %r12, %rsi
movl %ebp, 0x34(%rsp)
movl %ebp, %edx
movl %r15d, %ecx
callq 0x3fd6
leaq 0x1d8(%rsp), %rcx
movq 0x18(%rcx), %rax
movl 0x10(%rcx), %ecx
movq 0x18(%r13), %rdx
movq %rdx, 0x28(%rsp)
movl 0x10(%r13), %r8d
leaq 0x118(%rsp), %rdi
movq 0x18(%rdi), %rdx
movl 0x10(%rdi), %esi
movq %rdi, %r10
xorl %ebp, %ebp
testl %r14d, %r14d
movl $0x0, %edi
cmovgl %r14d, %edi
movq %rdi, 0x58(%rsp)
leaq 0xd8(%rsp), %r9
movq 0x18(%r9), %rdi
movq %rdi, 0x38(%rsp)
testl %ebx, %ebx
cmovlel %ebp, %ebx
movl %ebx, 0x24(%rsp)
movl 0x10(%r9), %edi
movl 0x8(%r9), %r9d
movl %edi, 0x14(%rsp)
imull %edi, %r9d
movl %r9d, 0x1c(%rsp)
movl 0x8(%r10), %edi
imull %esi, %edi
movl %edi, 0xc(%rsp)
movl 0x8(%r13), %edi
movl %r8d, 0x10(%rsp)
imull %r8d, %edi
movl %edi, 0x18(%rsp)
imull %ecx, %r14d
movl %r14d, 0x40(%rsp)
xorl %edi, %edi
xorl %r9d, %r9d
xorl %r10d, %r10d
xorl %r13d, %r13d
movl %ebp, 0x48(%rsp)
movl %ebp, %ebx
movl %edi, %r11d
movl %edi, %r8d
movl %r9d, %r14d
movl %r9d, %edi
movl %r10d, %r9d
movq 0x58(%rsp), %rbp
cmpl 0x24(%rsp), %r13d
je 0x7251
subq $0x1, %rbp
jb 0x722d
movslq %ebx, %rbx
movb (%rax,%rbx), %r15b
movslq %r8d, %r8
movq 0x28(%rsp), %r12
movb %r15b, (%r12,%r8)
movb 0x1(%rax,%rbx), %r15b
movslq %edi, %rdi
movb %r15b, (%rdx,%rdi)
movb 0x2(%rax,%rbx), %r15b
movslq %r9d, %r9
movq 0x38(%rsp), %r12
movb %r15b, (%r12,%r9)
addl 0x14(%rsp), %r9d
addl %esi, %edi
addl 0x10(%rsp), %r8d
addl %ecx, %ebx
jmp 0x71e7
incl %r13d
addl 0x1c(%rsp), %r10d
movl %r14d, %r9d
addl 0xc(%rsp), %r9d
movl %r11d, %edi
addl 0x18(%rsp), %edi
movl 0x48(%rsp), %ebp
addl 0x40(%rsp), %ebp
jmp 0x71c6
movq 0x1d0(%rsp), %rax
movl 0x1c8(%rsp), %ecx
movq 0xd0(%rsp), %rdx
movl 0xc8(%rsp), %esi
movq 0x90(%rsp), %rdi
movl 0x88(%rsp), %r8d
movq 0xb0(%rsp), %r9
movl 0xa8(%rsp), %r10d
movl 0xa0(%rsp), %r11d
imull %r10d, %r11d
movl %r11d, 0x6c(%rsp)
movl 0x80(%rsp), %r11d
imull %r8d, %r11d
movl %r11d, 0x68(%rsp)
movl 0xc0(%rsp), %r11d
imull %esi, %r11d
movl %r11d, 0x64(%rsp)
movl 0x34(%rsp), %r11d
imull %ecx, %r11d
movl %r11d, 0x34(%rsp)
xorl %r11d, %r11d
xorl %ebx, %ebx
xorl %ebp, %ebp
xorl %r15d, %r15d
xorl %r13d, %r13d
movl %r11d, 0x48(%rsp)
movl %r11d, %r14d
movl %ebx, 0x40(%rsp)
movl %ebx, %r11d
movl %ebp, 0xc(%rsp)
movl %ebp, %ebx
movl %r15d, 0x20(%rsp)
movl %r15d, %ebp
movq 0x58(%rsp), %r15
cmpl 0x24(%rsp), %r13d
je 0x736c
subq $0x1, %r15
jb 0x7340
movslq %r14d, %r14
movb (%rax,%r14), %r12b
movslq %r11d, %r11
movb %r12b, (%rdx,%r11)
movb 0x1(%rax,%r14), %r12b
movslq %ebx, %rbx
movb %r12b, (%rdi,%rbx)
movb 0x2(%rax,%r14), %r12b
movslq %ebp, %rbp
movb %r12b, (%r9,%rbp)
addl %r10d, %ebp
addl %r8d, %ebx
addl %esi, %r11d
addl %ecx, %r14d
jmp 0x7306
incl %r13d
movl 0x20(%rsp), %r15d
addl 0x6c(%rsp), %r15d
movl 0xc(%rsp), %ebp
addl 0x68(%rsp), %ebp
movl 0x40(%rsp), %ebx
addl 0x64(%rsp), %ebx
movl 0x48(%rsp), %r11d
addl 0x34(%rsp), %r11d
jmp 0x72dd
leaq 0x198(%rsp), %rdi
leaq 0x178(%rsp), %r15
movq %r15, %rsi
movl 0x54(%rsp), %ebx
movl %ebx, %edx
callq 0x76ea
leaq 0x118(%rsp), %rdi
leaq 0x158(%rsp), %rsi
movl %ebx, %edx
callq 0x76ea
leaq 0xd8(%rsp), %rdi
leaq 0x138(%rsp), %r12
movq %r12, %rsi
movl %ebx, %edx
callq 0x76ea
movq 0x18(%r15), %rax
movq %rax, 0x48(%rsp)
movl 0x10(%r15), %eax
movq 0x18(%r12), %rcx
movq %rcx, 0x40(%rsp)
movl 0x10(%r12), %r14d
movl 0x8(%r12), %ecx
imull %r14d, %ecx
movl %ecx, 0xc(%rsp)
movl 0x8(%r15), %ecx
movl %eax, %ebx
imull %eax, %ecx
movl %ecx, 0x20(%rsp)
xorl %eax, %eax
xorl %ecx, %ecx
xorl %edx, %edx
xorl %esi, %esi
xorl %edi, %edi
movl %eax, %r8d
movl %ecx, %r9d
movl %edx, %r10d
movl %esi, %r11d
movq 0x58(%rsp), %r15
cmpl 0x24(%rsp), %edi
je 0x746e
subq $0x1, %r15
jb 0x745a
movslq %r8d, %r8
movq 0x48(%rsp), %r12
movb (%r12,%r8), %bpl
movslq %r9d, %r9
movq 0x28(%rsp), %r12
movb %bpl, (%r12,%r9)
movslq %r10d, %r10
movq 0x40(%rsp), %r12
movb (%r12,%r10), %bpl
movslq %r11d, %r11
movq 0x38(%rsp), %r12
movb %bpl, (%r12,%r11)
addl 0x14(%rsp), %r11d
addl %r14d, %r10d
addl 0x10(%rsp), %r9d
addl %ebx, %r8d
jmp 0x7412
incl %edi
addl 0x1c(%rsp), %esi
addl 0xc(%rsp), %edx
addl 0x18(%rsp), %ecx
addl 0x20(%rsp), %eax
jmp 0x73fb
cvtsi2ssl 0x60(%rsp), %xmm0
movss %xmm0, 0x28(%rsp)
leaq 0x198(%rsp), %r15
leaq 0x178(%rsp), %r13
movq %r15, %rdi
movq %r13, %rsi
movl 0x54(%rsp), %ebp
movl %ebp, %edx
callq 0x78ee
leaq 0xd8(%rsp), %rdi
leaq 0x138(%rsp), %r12
movq %r12, %rsi
movl %ebp, %edx
movss 0x28(%rsp), %xmm0
callq 0x78ee
movq %r15, %rdi
movq %r13, %rsi
callq 0x7cac
movss %xmm0, 0x18(%rsp)
leaq 0x118(%rsp), %rdi
leaq 0x158(%rsp), %rbp
movq %rbp, %rsi
callq 0x7cac
movss %xmm0, 0x1c(%rsp)
leaq 0xd8(%rsp), %rdi
movq %r12, %rsi
callq 0x7cac
movss %xmm0, 0x10(%rsp)
leaq 0xb8(%rsp), %rdi
movq %r13, %rsi
callq 0x7cac
movss %xmm0, 0x14(%rsp)
leaq 0x78(%rsp), %rdi
movq %rbp, %rsi
callq 0x7cac
movss %xmm0, 0x38(%rsp)
leaq 0x98(%rsp), %rdi
movq %r12, %rsi
callq 0x7cac
movss %xmm0, 0x28(%rsp)
movq 0xda8a(%rip), %rdi      # 0x14fd0
leaq 0x9643(%rip), %rsi      # 0x10b90
callq 0x2170
movq %rax, %rdi
movss 0x18(%rsp), %xmm0
callq 0x2100
leaq 0x9635(%rip), %rsi      # 0x10b9c
movq %rax, %rdi
callq 0x2170
movq %rax, %rdi
movss 0x1c(%rsp), %xmm0
callq 0x2100
leaq 0x9627(%rip), %rsi      # 0x10bab
movq %rax, %rdi
callq 0x2170
movq %rax, %rdi
movss 0x10(%rsp), %xmm0
callq 0x2100
leaq 0x9618(%rip), %rsi      # 0x10bb9
movq %rax, %rdi
callq 0x2170
movq %rax, %rdi
movss 0x14(%rsp), %xmm0
callq 0x2100
leaq 0x960a(%rip), %rsi      # 0x10bc8
movq %rax, %rdi
callq 0x2170
movq %rax, %rdi
movss 0x38(%rsp), %xmm0
callq 0x2100
leaq 0x95fb(%rip), %rsi      # 0x10bd6
movq %rax, %rdi
callq 0x2170
movq %rax, %rdi
movss 0x28(%rsp), %xmm0
callq 0x2100
movq %rax, %rdi
callq 0x20c0
movq 0x110(%rsp), %rax
movl 0x108(%rsp), %ecx
movq 0x18(%rbp), %rdx
movl 0x10(%rbp), %esi
movl 0x8(%rbp), %edi
imull %esi, %edi
movl %edi, 0x14(%rsp)
movl 0x100(%rsp), %edi
imull %ecx, %edi
movl %edi, 0x10(%rsp)
xorl %edi, %edi
xorl %r8d, %r8d
xorl %r9d, %r9d
xorl %r10d, %r10d
xorl %ebp, %ebp
movl %edi, 0x28(%rsp)
movl %edi, %r12d
movl %r8d, 0x38(%rsp)
movl %r8d, %r13d
movl %r9d, %r15d
movl %r9d, %edi
movl %r10d, %r8d
movq 0x58(%rsp), %r9
cmpl 0x24(%rsp), %ebp
je 0x76c6
subq $0x1, %r9
jb 0x76a0
movslq %r12d, %r12
movl %r10d, %r11d
movq 0x48(%rsp), %r10
movb (%r10,%r12), %r10b
movslq %r13d, %r13
movb %r10b, (%rax,%r13)
movslq %edi, %rdi
movb (%rdx,%rdi), %r10b
movb %r10b, 0x1(%rax,%r13)
movslq %r8d, %r8
movq 0x40(%rsp), %r10
movb (%r10,%r8), %r10b
movb %r10b, 0x2(%rax,%r13)
movl %r11d, %r10d
addl %r14d, %r8d
addl %esi, %edi
addl %ecx, %r13d
addl %ebx, %r12d
jmp 0x7657
incl %ebp
addl 0xc(%rsp), %r10d
movl %r15d, %r9d
addl 0x14(%rsp), %r9d
movl 0x38(%rsp), %r8d
addl 0x10(%rsp), %r8d
movl 0x28(%rsp), %edi
addl 0x20(%rsp), %edi
jmp 0x7634
leaq 0xf8(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x411c
addq $0x1f8, %rsp            # imm = 0x1F8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq