// File: rishabh-battulwar[P]imageprocessing/./include/ImageProc.h
// Function: ImageProc::hist_equal(char const*, char const*, int, int)
void ImageProc::hist_equal(const char *infile, const char *outfile, int width, int height)
{
	//########### If image == bw #########
	// Image img_bw("bw", width, height);

	// img_bw.read_image(infile, width, height);

	// int histogram_bins[256] = {0};

	// for(int i = 0; i < height; i++)
	// 	for(int j = 0; j < width; j++)
	// 		if((img_bw(i, j, 0) >= 0) && (img_bw(i, j, 0) < 256))
	// 			histogram_bins[img_bw(i, j, 0)]++;


	// int hist_cumulative[256] = {0};
	// hist_cumulative[0] = histogram_bins[0];
	// for(int i = 1; i < 256; i++)
	// 	hist_cumulative[i] = hist_cumulative[i-1] + histogram_bins[i];

	// int hist_cumulative_copy[256] = {0};
	// int curr_bin_count = 0, prev_bin_count = 0;
	// double value =  0;
	// for(int i = 0; i < height; i++)
	// 	for(int j = 0; j < width; j++)
	// 		if      (img_bw(i, j, 0) < 0  ) img_bw.imgdata[(i)*width*1 + (j)*1 + 0] = 0  ;
	// 		else if (img_bw(i, j, 0) > 255) img_bw.imgdata[(i)*width*1 + (j)*1 + 0] = 255;
	// 		else
	// 		{
	// 			++hist_cumulative_copy[img_bw(i, j, 0)];
	// 			curr_bin_count = hist_cumulative_copy[img_bw(i, j, 0)];
	// 			prev_bin_count = hist_cumulative[img_bw(i, j, 0) - 1];
	// 			value = floor(255.0 * (prev_bin_count + curr_bin_count) / hist_cumulative[255]);
	// 			img_bw.imgdata[(i)*width*1 + (j)*1 + 0] = value;
	// 			value = 0; curr_bin_count = 0; prev_bin_count = 0;
	// 		}

	// img_bw.write_image(outfile, width, height);
	//###################################


	//######## If image == color ########
	Image img_color("color", width, height);

	img_color.read_image(infile, width, height);

	int histogram_bins[256][3] = {0};

	for(int i = 0; i < img_color.rows; i++)
		for(int j = 0; j < img_color.cols; j++)
			for(int k = 0; k < img_color.channels; k++)
				if((img_color(i, j, k) >= 0) && (img_color(i, j, k) < 256))
					histogram_bins[img_color(i, j, k)][k]++;


	int hist_cumulative[256][3] = {0};
	for(int k = 0; k < 3; k++)
		hist_cumulative[0][k] = histogram_bins[0][k];
	for(int i = 1; i < 256; i++)
		for(int k = 0; k < 3; k++)
			hist_cumulative[i][k] = hist_cumulative[i-1][k] + histogram_bins[i][k];

	// std::ofstream file;

	// file.open("rt2.txt");
	// for(int i = 0; i < 256; i++)
	// 	file << i << "\t" <<hist_cumulative[i][0] << "\n";
	// file.close();

	// file.open("gt2.txt");
	// for(int i = 0; i < 256; i++)
	// 	file << i << "\t" <<hist_cumulative[i][1] << "\n";
	// file.close();

	// file.open("bt2.txt");
	// for(int i = 0; i < 256; i++)
	// 	file << i << "\t" <<hist_cumulative[i][2] << "\n";
	// file.close();

	int hist_cumulative_copy[256][3] = {0};
	int curr_bin_count = 0, prev_bin_count = 0;
	double value =  0;

	for(int i = 0; i < img_color.rows; i++)
		for(int j = 0; j < img_color.cols; j++)
			for(int k = 0; k < 3; k++)
				if      (img_color.getvalue(i,j,k) < 0  ) img_color.setvalue(i,j,k,0);
				else if (img_color.getvalue(i,j,k) > 255) img_color.setvalue(i,j,k,255);
				else
				{
					++hist_cumulative_copy[img_color(i, j, k)][k];
					curr_bin_count = hist_cumulative_copy[img_color(i, j, k)][k];
					prev_bin_count = hist_cumulative[img_color(i, j, k) - 1][k];
					value = floor(255.0 * (prev_bin_count + curr_bin_count) / hist_cumulative[255][k]);
					img_color.setvalue(i,j,k,value);
					value = 0; curr_bin_count = 0; prev_bin_count = 0;
				}


	img_color.write_image(outfile, img_color.cols, img_color.rows);
	//###################################
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x24a0, %rsp           # imm = 0x24A0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
leaq 0x10172(%rip), %rsi     # 0x1c5e8
leaq -0x38(%rbp), %rdi
movq %rdi, -0x2498(%rbp)
callq 0x7eb0
movq -0x2498(%rbp), %rdi
movq -0x8(%rbp), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
callq 0x7f70
jmp 0xc49e
leaq -0xc50(%rbp), %rdi
xorl %esi, %esi
movl $0xc00, %edx            # imm = 0xC00
callq 0x2100
movl $0x0, -0xc54(%rbp)
movl -0xc54(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0xc5d8
movl $0x0, -0xc58(%rbp)
movl -0xc58(%rbp), %eax
cmpl -0x30(%rbp), %eax
jge 0xc5c2
movl $0x0, -0xc5c(%rbp)
movl -0xc5c(%rbp), %eax
cmpl -0x28(%rbp), %eax
jge 0xc5ac
movl -0xc54(%rbp), %esi
movl -0xc58(%rbp), %edx
movl -0xc5c(%rbp), %ecx
leaq -0x38(%rbp), %rdi
callq 0x8300
cmpl $0x0, %eax
jl 0xc596
movl -0xc54(%rbp), %esi
movl -0xc58(%rbp), %edx
movl -0xc5c(%rbp), %ecx
leaq -0x38(%rbp), %rdi
callq 0x8300
cmpl $0x100, %eax            # imm = 0x100
jge 0xc596
movl -0xc54(%rbp), %esi
movl -0xc58(%rbp), %edx
movl -0xc5c(%rbp), %ecx
leaq -0x38(%rbp), %rdi
callq 0x8300
movslq %eax, %rcx
leaq -0xc50(%rbp), %rax
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movslq -0xc5c(%rbp), %rcx
movl (%rax,%rcx,4), %edx
addl $0x1, %edx
movl %edx, (%rax,%rcx,4)
jmp 0xc596
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x1b2c0
jmp 0xc989
jmp 0xc598
movl -0xc5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc5c(%rbp)
jmp 0xc4ed
jmp 0xc5ae
movl -0xc58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc58(%rbp)
jmp 0xc4d4
jmp 0xc5c4
movl -0xc54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc54(%rbp)
jmp 0xc4bb
leaq -0x1860(%rbp), %rdi
xorl %esi, %esi
movl $0xc00, %edx            # imm = 0xC00
callq 0x2100
movl $0x0, -0x1864(%rbp)
cmpl $0x3, -0x1864(%rbp)
jge 0xc62b
movslq -0x1864(%rbp), %rax
movl -0xc50(%rbp,%rax,4), %ecx
movslq -0x1864(%rbp), %rax
movl %ecx, -0x1860(%rbp,%rax,4)
movl -0x1864(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1864(%rbp)
jmp 0xc5f5
movl $0x1, -0x1868(%rbp)
cmpl $0x100, -0x1868(%rbp)   # imm = 0x100
jge 0xc6e1
movl $0x0, -0x186c(%rbp)
cmpl $0x3, -0x186c(%rbp)
jge 0xc6cb
movl -0x1868(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rcx
leaq -0x1860(%rbp), %rax
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movslq -0x186c(%rbp), %rcx
movl (%rax,%rcx,4), %edx
movslq -0x1868(%rbp), %rcx
leaq -0xc50(%rbp), %rax
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movslq -0x186c(%rbp), %rcx
addl (%rax,%rcx,4), %edx
movslq -0x1868(%rbp), %rcx
leaq -0x1860(%rbp), %rax
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movslq -0x186c(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movl -0x186c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x186c(%rbp)
jmp 0xc64f
jmp 0xc6cd
movl -0x1868(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1868(%rbp)
jmp 0xc635
leaq -0x2470(%rbp), %rdi
xorl %esi, %esi
movl $0xc00, %edx            # imm = 0xC00
callq 0x2100
movl $0x0, -0x2474(%rbp)
movl $0x0, -0x2478(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x2480(%rbp)
movl $0x0, -0x2484(%rbp)
movl -0x2484(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0xc962
movl $0x0, -0x2488(%rbp)
movl -0x2488(%rbp), %eax
cmpl -0x30(%rbp), %eax
jge 0xc94c
movl $0x0, -0x248c(%rbp)
cmpl $0x3, -0x248c(%rbp)
jge 0xc936
movl -0x2484(%rbp), %esi
movl -0x2488(%rbp), %edx
movl -0x248c(%rbp), %ecx
leaq -0x38(%rbp), %rdi
callq 0x83b0
cmpl $0x0, %eax
jge 0xc79f
movl -0x2484(%rbp), %esi
movl -0x2488(%rbp), %edx
movl -0x248c(%rbp), %ecx
leaq -0x38(%rbp), %rdi
xorl %r8d, %r8d
callq 0x83f0
jmp 0xc920
movl -0x2484(%rbp), %esi
movl -0x2488(%rbp), %edx
movl -0x248c(%rbp), %ecx
leaq -0x38(%rbp), %rdi
callq 0x83b0
cmpl $0xff, %eax
jle 0xc7e7
movl -0x2484(%rbp), %esi
movl -0x2488(%rbp), %edx
movl -0x248c(%rbp), %ecx
leaq -0x38(%rbp), %rdi
movl $0xff, %r8d
callq 0x83f0
jmp 0xc91e
movl -0x2484(%rbp), %esi
movl -0x2488(%rbp), %edx
movl -0x248c(%rbp), %ecx
leaq -0x38(%rbp), %rdi
callq 0x8300
movslq %eax, %rcx
leaq -0x2470(%rbp), %rax
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movslq -0x248c(%rbp), %rcx
movl (%rax,%rcx,4), %edx
addl $0x1, %edx
movl %edx, (%rax,%rcx,4)
movl -0x2484(%rbp), %esi
movl -0x2488(%rbp), %edx
movl -0x248c(%rbp), %ecx
leaq -0x38(%rbp), %rdi
callq 0x8300
movslq %eax, %rcx
leaq -0x2470(%rbp), %rax
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movslq -0x248c(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x2474(%rbp)
movl -0x2484(%rbp), %esi
movl -0x2488(%rbp), %edx
movl -0x248c(%rbp), %ecx
leaq -0x38(%rbp), %rdi
callq 0x8300
subl $0x1, %eax
movslq %eax, %rcx
leaq -0x1860(%rbp), %rax
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movslq -0x248c(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x2478(%rbp)
movl -0x2478(%rbp), %eax
addl -0x2474(%rbp), %eax
cvtsi2sd %eax, %xmm1
movsd 0xfc12(%rip), %xmm0     # 0x1c4c8
mulsd %xmm1, %xmm0
movslq -0x248c(%rbp), %rax
cvtsi2sdl -0xc6c(%rbp,%rax,4), %xmm1
divsd %xmm1, %xmm0
callq 0x2330
movsd %xmm0, -0x2480(%rbp)
movl -0x2484(%rbp), %esi
movl -0x2488(%rbp), %edx
movl -0x248c(%rbp), %ecx
cvttsd2si -0x2480(%rbp), %r8d
leaq -0x38(%rbp), %rdi
callq 0x83f0
xorps %xmm0, %xmm0
movsd %xmm0, -0x2480(%rbp)
movl $0x0, -0x2474(%rbp)
movl $0x0, -0x2478(%rbp)
jmp 0xc920
jmp 0xc922
movl -0x248c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x248c(%rbp)
jmp 0xc74f
jmp 0xc938
movl -0x2488(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2488(%rbp)
jmp 0xc736
jmp 0xc94e
movl -0x2484(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2484(%rbp)
jmp 0xc71d
movq -0x10(%rbp), %rsi
movl -0x30(%rbp), %edx
movl -0x2c(%rbp), %ecx
leaq -0x38(%rbp), %rdi
callq 0x8150
jmp 0xc977
leaq -0x38(%rbp), %rdi
callq 0x1b2c0
addq $0x24a0, %rsp           # imm = 0x24A0
popq %rbp
retq
movq -0x40(%rbp), %rdi
callq 0x2360
nopw %cs:(%rax,%rax)