// File: /workspace/github_cpp_makefile_star2_O2/sorazy[P]canny/main.cpp
// Function: main
int main(int argc, char **argv)
{
	// Exit program if proper arguments are not provided by user
	if (argc != 4)
	{
		cout << "Proper syntax: ./a.out <input_filename> <high_threshold> <sigma_value>" << endl;
		return 0;
	}

	// Exit program if file doesn't open
	string filename(argv[1]);
	string path = "./input_images/" + filename;
	ifstream infile(path, ios::binary);
	if (!infile.is_open())
	{
		cout << "File " << path << " not found in directory." << endl;
		return 0;
	}	

	// Opening output files
	ofstream img1("./output_images/canny_mag.pgm", ios::binary);
	ofstream img2("./output_images/canny_peaks.pgm", ios::binary);		
	ofstream img3("./output_images/canny_final.pgm", ios::binary);

	::hi = stoi(argv[2]);
	::lo = .35 * hi;
	::sig = stoi(argv[3]);

	// Storing header information and copying into the new ouput images
	infile >> ::type >> ::width >> ::height >> ::intensity;
	img1 << type << endl << width << " " << height << endl << intensity << endl;
	img2 << type << endl << width << " " << height << endl << intensity << endl;
	img3 << type << endl << width << " " << height << endl << intensity << endl;

	// These matrices will hold the integer values of the input image and masks.
	// I'm dynamically allocating arrays to easily pass them into functions.
	double **pic = new double*[height], **mag = new double*[height], **final = new double*[height];
	double **x = new double*[height], **y = new double*[height];

	for (int i = 0; i < height; i++)
	{
		pic[i] = new double[width];
		mag[i] = new double[width];
		final[i] = new double[width];
		x[i] = new double[width];
		y[i] = new double[width];
	}

	// Reading in the input image as integers
	for (int i = 0; i < height; i++)
		for (int j = 0; j < width; j++)
			pic[i][j] = (int)infile.get();

	// Create the magniute matrix
	magnitude_matrix(pic, mag, x, y);

	// Get all the peaks and store them in vector
	HashMap *peaks = new HashMap();
	vector<Point*> v = peak_detection(mag, peaks, x, y);

	// Go through the vector and call the recursive function and each point. If the value
	// in the mag matrix is hi, then immediately accept it in final. If lo, then immediately
	// reject. If between lo and hi, then check if it's next to a hi pixel using recursion
	HashMap *h = new HashMap();
	int a, b;
	for (int i = 0; i < v.size(); i++)
	{
		a = v.at(i)->x;
		b = v.at(i)->y;

		if (mag[a][b] >= hi)
			final[a][b] = 255;
		else if (mag[a][b] < lo)
			final[a][b] = 0;
		else
			recursiveDT(mag, final, h, peaks, a, b, 0);
	}

	// ================================= IMAGE OUTPUT =================================
	// Outputting the 'mag' matrix to img1. It's very important to cast it to a char.
	// To make sure that the decimal doesn't produce any wonky results, cast to an int
	// ================================= IMAGE OUTPUT =================================
	for (int i = 0; i < height; i++)
		for (int j = 0; j < width; j++)
			img1 << (char)((int)mag[i][j]);

	// Outputting the points stored in the vector to img2
	int k = 0;
	for (int i = 0; i < v.size(); i++)
	{
		while(k++ != (v.at(i)->x * height + v.at(i)->y - 1))
			img2 << (char)(0);

		img2 << (char)(255);
	}

	// Output the 'final' matrix to img1
	for (int i = 0; i < height; i++)
		for (int j = 0; j < width; j++)
			img3 << (char)((int)final[i][j]);		

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x8a8, %rsp            # imm = 0x8A8
cmpl $0x4, %edi
jne 0x27ae
movq %rsi, %rbx
movq 0x8(%rsi), %rsi
leaq -0xb8(%rbp), %r14
leaq -0x2c0(%rbp), %rdx
movq %r14, %rdi
callq 0x2b8e
leaq 0x1bf2(%rip), %rsi      # 0x405f
leaq -0x98(%rbp), %rdi
movq %r14, %rdx
callq 0x2bc9
leaq -0x2c0(%rbp), %rdi
leaq -0x98(%rbp), %rsi
pushq $0x4
popq %rdx
callq 0x2210
leaq -0x248(%rbp), %rdi
callq 0x2060
testb %al, %al
je 0x27ce
leaq 0x1be1(%rip), %rsi      # 0x408e
leaq -0x8c0(%rbp), %rdi
pushq $0x4
popq %rdx
callq 0x2190
leaq 0x1be9(%rip), %rsi      # 0x40ac
leaq -0x4c0(%rbp), %rdi
pushq $0x4
popq %rdx
callq 0x2190
leaq 0x1bf3(%rip), %rsi      # 0x40cc
leaq -0x6c0(%rbp), %rdi
pushq $0x4
popq %rdx
callq 0x2190
movq 0x10(%rbx), %rsi
leaq -0x60(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x2b8e
leaq -0x60(%rbp), %rdi
pushq $0xa
popq %rdx
xorl %esi, %esi
callq 0x2c3f
movl %eax, 0x3c73(%rip)      # 0x6180
leaq -0x60(%rbp), %rdi
callq 0x20c0
cvtsi2sdl 0x3c62(%rip), %xmm0 # 0x6180
mulsd 0x1ae2(%rip), %xmm0     # 0x4008
cvttsd2si %xmm0, %eax
movl %eax, 0x3c54(%rip)      # 0x6184
movq 0x18(%rbx), %rsi
leaq -0x60(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x2b8e
leaq -0x60(%rbp), %rdi
pushq $0xa
popq %rdx
xorl %esi, %esi
callq 0x2c3f
cvtsi2sd %eax, %xmm0
movsd %xmm0, 0x3c2d(%rip)     # 0x6188
leaq -0x60(%rbp), %rdi
callq 0x20c0
leaq 0x3bfe(%rip), %rsi      # 0x6169
leaq -0x2c0(%rbp), %rdi
callq 0x2c60
leaq 0x3bfa(%rip), %rsi      # 0x6178
movq %rax, %rdi
callq 0x2100
leaq 0x3be7(%rip), %rsi      # 0x6174
movq %rax, %rdi
callq 0x2100
leaq 0x3be0(%rip), %rsi      # 0x617c
movq %rax, %rdi
callq 0x2100
leaq 0x3bbe(%rip), %rsi      # 0x6169
leaq -0x8c0(%rbp), %rdi
callq 0x2160
movq %rax, %rdi
callq 0x20d0
movl 0x3bb3(%rip), %esi      # 0x6178
movq %rax, %rdi
callq 0x2240
leaq 0x1c3b(%rip), %rsi      # 0x420f
movq %rax, %rdi
callq 0x2160
movl 0x3b92(%rip), %esi      # 0x6174
movq %rax, %rdi
callq 0x2240
movq %rax, %rdi
callq 0x20d0
movl 0x3b84(%rip), %esi      # 0x617c
movq %rax, %rdi
callq 0x2240
movq %rax, %rdi
callq 0x20d0
leaq 0x3b5a(%rip), %rsi      # 0x6169
leaq -0x4c0(%rbp), %rdi
callq 0x2160
movq %rax, %rdi
callq 0x20d0
movl 0x3b4f(%rip), %esi      # 0x6178
movq %rax, %rdi
callq 0x2240
leaq 0x1bd7(%rip), %rsi      # 0x420f
movq %rax, %rdi
callq 0x2160
movl 0x3b2e(%rip), %esi      # 0x6174
movq %rax, %rdi
callq 0x2240
movq %rax, %rdi
callq 0x20d0
movl 0x3b20(%rip), %esi      # 0x617c
movq %rax, %rdi
callq 0x2240
movq %rax, %rdi
callq 0x20d0
leaq 0x3af6(%rip), %rsi      # 0x6169
leaq -0x6c0(%rbp), %rdi
callq 0x2160
movq %rax, %rdi
callq 0x20d0
movl 0x3aeb(%rip), %esi      # 0x6178
movq %rax, %rdi
callq 0x2240
leaq 0x1b73(%rip), %rsi      # 0x420f
movq %rax, %rdi
callq 0x2160
movl 0x3aca(%rip), %esi      # 0x6174
movq %rax, %rdi
callq 0x2240
movq %rax, %rdi
callq 0x20d0
movl 0x3abc(%rip), %esi      # 0x617c
movq %rax, %rdi
callq 0x2240
movq %rax, %rdi
callq 0x20d0
movslq 0x3a9d(%rip), %r14      # 0x6174
leaq (,%r14,8), %r15
testq %r14, %r14
pushq $-0x1
popq %rax
cmovsq %rax, %r15
movq %r15, %rdi
callq 0x2030
movq %rax, %r12
movq %r15, %rdi
callq 0x2030
movq %rax, -0x38(%rbp)
movq %r15, %rdi
callq 0x2030
movq %rax, %rbx
movq %r15, %rdi
callq 0x2030
movq %rax, -0x68(%rbp)
movq %rbx, -0x40(%rbp)
movq %r15, %rdi
callq 0x2030
movq %rax, -0x70(%rbp)
movslq 0x3a4a(%rip), %r13      # 0x6178
leaq (,%r13,8), %rbx
testq %r13, %r13
pushq $-0x1
popq %rax
cmovsq %rax, %rbx
xorl %r15d, %r15d
testl %r14d, %r14d
movl $0x0, %eax
cmovgl %r14d, %eax
movq %rax, -0x78(%rbp)
cmpq %r15, -0x78(%rbp)
je 0x280c
movq %rbx, %rdi
callq 0x2030
movq %rax, (%r12,%r15,8)
movq %rbx, %rdi
callq 0x2030
movq -0x38(%rbp), %rcx
movq %rax, (%rcx,%r15,8)
movq %rbx, %rdi
callq 0x2030
movq -0x40(%rbp), %rcx
movq %rax, (%rcx,%r15,8)
movq %rbx, %rdi
callq 0x2030
movq -0x68(%rbp), %rcx
movq %rax, (%rcx,%r15,8)
movq %rbx, %rdi
callq 0x2030
movq -0x70(%rbp), %rcx
movq %rax, (%rcx,%r15,8)
incq %r15
jmp 0x2753
movq 0x381b(%rip), %rdi      # 0x5fd0
leaq 0x185c(%rip), %rsi      # 0x4018
callq 0x2160
movq %rax, %rdi
callq 0x20d0
jmp 0x2aae
movq 0x37fb(%rip), %rdi      # 0x5fd0
leaq 0x1893(%rip), %rsi      # 0x406f
callq 0x2160
leaq -0x98(%rbp), %rsi
movq %rax, %rdi
callq 0x2150
leaq 0x187e(%rip), %rsi      # 0x4075
movq %rax, %rdi
callq 0x2160
movq %rax, %rdi
callq 0x20d0
jmp 0x2a8a
xorl %ebx, %ebx
leaq -0x2c0(%rbp), %r15
movslq %r14d, %rax
cmpq %rax, %rbx
jge 0x2856
xorl %r14d, %r14d
movslq %r13d, %rax
cmpq %rax, %r14
jge 0x284a
movq %r15, %rdi
callq 0x21b0
cvtsi2sd %eax, %xmm0
movq (%r12,%rbx,8), %rax
movsd %xmm0, (%rax,%r14,8)
incq %r14
movl 0x3930(%rip), %r13d     # 0x6178
jmp 0x2820
incq %rbx
movl 0x3920(%rip), %r14d     # 0x6174
jmp 0x2815
movq %r12, %rdi
movq -0x38(%rbp), %rsi
movq -0x68(%rbp), %rdx
movq -0x70(%rbp), %rbx
movq %rbx, %rcx
callq 0x2e88
pushq $0x40
popq %rdi
callq 0x2170
movq %rax, %r14
movq %rax, %rdi
callq 0x3836
leaq -0x60(%rbp), %rdi
movq -0x38(%rbp), %rsi
movq %r14, %rdx
movq -0x68(%rbp), %rcx
movq %rbx, %r8
callq 0x3200
pushq $0x40
popq %rdi
callq 0x2170
movq %rax, %rbx
movq %rax, %rdi
callq 0x3836
xorl %r13d, %r13d
leaq -0x60(%rbp), %r12
movq -0x58(%rbp), %rax
subq -0x60(%rbp), %rax
sarq $0x3, %rax
cmpq %r13, %rax
jbe 0x2951
movq %r12, %rdi
movq %r13, %rsi
callq 0x2c82
movq (%rax), %rax
movslq (%rax), %r15
movq %r12, %rdi
movq %r13, %rsi
callq 0x2c82
movq (%rax), %rax
movslq 0x4(%rax), %r9
movq -0x38(%rbp), %rax
movq (%rax,%r15,8), %rax
cvtsi2sdl 0x3887(%rip), %xmm0 # 0x6180
movsd (%rax,%r9,8), %xmm1
ucomisd %xmm0, %xmm1
movsd 0x1705(%rip), %xmm0     # 0x4010
jae 0x291f
cvtsi2sdl 0x386f(%rip), %xmm2 # 0x6184
xorpd %xmm0, %xmm0
ucomisd %xmm1, %xmm2
jbe 0x292f
movq -0x40(%rbp), %rax
movq (%rax,%r15,8), %rax
movsd %xmm0, (%rax,%r9,8)
jmp 0x2949
andl $0x0, (%rsp)
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq %rbx, %rdx
movq %r14, %rcx
movl %r15d, %r8d
callq 0x3495
incq %r13
jmp 0x28b1
xorl %ebx, %ebx
leaq -0x8c0(%rbp), %r15
movslq 0x3813(%rip), %rax      # 0x6174
xorl %r14d, %r14d
cmpq %rax, %rbx
jge 0x2998
movslq 0x3808(%rip), %rax      # 0x6178
cmpq %rax, %r14
jge 0x2993
movq -0x38(%rbp), %rax
movq (%rax,%rbx,8), %rax
cvttsd2si (%rax,%r14,8), %eax
movsbl %al, %esi
movq %r15, %rdi
callq 0x21a0
incq %r14
jmp 0x2969
incq %rbx
jmp 0x295a
leaq -0x60(%rbp), %r15
xorl %r13d, %r13d
movq -0x58(%rbp), %rax
subq -0x60(%rbp), %rax
sarq $0x3, %rax
cmpq %r14, %rax
jbe 0x2a16
decl %r13d
movq %r15, %rdi
movq %r14, %rsi
callq 0x2c82
movq (%rax), %rax
movl (%rax), %r12d
movl 0x37aa(%rip), %ebx      # 0x6174
movq %r15, %rdi
movq %r14, %rsi
callq 0x2c82
imull %r12d, %ebx
movq (%rax), %rax
movl 0x4(%rax), %eax
addl %ebx, %eax
decl %eax
leal 0x1(%r13), %ebx
cmpl %eax, %ebx
je 0x29fe
leaq -0x4c0(%rbp), %rdi
xorl %esi, %esi
callq 0x21a0
movl %ebx, %r13d
jmp 0x29b3
leaq -0x4c0(%rbp), %rdi
pushq $-0x1
popq %rsi
callq 0x21a0
addl $0x2, %r13d
incq %r14
jmp 0x299f
xorl %ebx, %ebx
leaq -0x6c0(%rbp), %r14
movq -0x40(%rbp), %r12
movslq 0x374a(%rip), %rax      # 0x6174
cmpq %rax, %rbx
jge 0x2a5d
xorl %r15d, %r15d
movslq 0x373f(%rip), %rax      # 0x6178
cmpq %rax, %r15
jge 0x2a58
movq (%r12,%rbx,8), %rax
cvttsd2si (%rax,%r15,8), %eax
movsbl %al, %esi
movq %r14, %rdi
callq 0x21a0
incq %r15
jmp 0x2a32
incq %rbx
jmp 0x2a23
leaq -0x60(%rbp), %rdi
callq 0x2e24
leaq -0x6c0(%rbp), %rdi
callq 0x21d0
leaq -0x4c0(%rbp), %rdi
callq 0x21d0
leaq -0x8c0(%rbp), %rdi
callq 0x21d0
leaq -0x2c0(%rbp), %rdi
callq 0x2070
leaq -0x98(%rbp), %rdi
callq 0x20c0
leaq -0xb8(%rbp), %rdi
callq 0x20c0
xorl %eax, %eax
addq $0x8a8, %rsp            # imm = 0x8A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbx, %rdi
movq %rax, %rbx
pushq $0x40
popq %rsi
callq 0x2180
jmp 0x2b35
jmp 0x2b32
jmp 0x2b2d
movq %rax, %rbx
pushq $0x40
popq %rsi
movq %r14, %rdi
callq 0x2180
jmp 0x2b3e
jmp 0x2b2d
jmp 0x2b2d
jmp 0x2b2d
jmp 0x2b2d
jmp 0x2b2d
jmp 0x2af4
jmp 0x2b2d
movq %rax, %rbx
leaq -0x60(%rbp), %rdi
callq 0x20c0
jmp 0x2b3e
jmp 0x2b2d
movq %rax, %rbx
jmp 0x2b4a
movq %rax, %rbx
jmp 0x2b56
jmp 0x2b1c
jmp 0x2b2d
movq %rax, %rbx
jmp 0x2b6e
movq %rax, %rbx
jmp 0x2b7a
movq %rax, %rbx
jmp 0x2b62
jmp 0x2b2d
jmp 0x2b32
jmp 0x2b32
jmp 0x2b2d
jmp 0x2b32
jmp 0x2b32
movq %rax, %rbx
jmp 0x2b3e
movq %rax, %rbx
leaq -0x60(%rbp), %rdi
callq 0x2e24
leaq -0x6c0(%rbp), %rdi
callq 0x21d0
leaq -0x4c0(%rbp), %rdi
callq 0x21d0
leaq -0x8c0(%rbp), %rdi
callq 0x21d0
leaq -0x2c0(%rbp), %rdi
callq 0x2070
leaq -0x98(%rbp), %rdi
callq 0x20c0
leaq -0xb8(%rbp), %rdi
callq 0x20c0
movq %rbx, %rdi
callq 0x2250