// File: /workspace/github_cpp_makefile_star2_O3/Matheus-Aguilar[P]Huffman/main.cpp
// Function: compressFile(char*, char*)
void compressFile(char *in, char *out){
	
	ifstream fin; //Input file
	fin.open(in, ios::binary); 

	ofstream fout; //Output file
	fout.open(out, ofstream::out);

	vector<char> content; //Content of the file
	vector<bool> bits; //Encoded bits

	int freq[256] = {0}; //Frequency array

	//Copying each caracter to vector and calculating the frequencies
	unsigned char character;
	for(int i = 0; fin.peek() != -1; ++i){
		fin.read(reinterpret_cast<char *>(&character), sizeof(unsigned char));
		content.push_back(character);
		++freq[character];
	}

	HuffmanTree tree(freq); //Build the tree
	tree.compress(bits, content); //Save the huffman encoded bits into the vector

	//Saving the frequency dictionary into the file
	fout.write(reinterpret_cast<const char *>(freq), sizeof(freq));
	//Copying the number of bits of the huffman encoding
	int HuffmanSize = bits.size();
	fout.write(reinterpret_cast<const char *>(&HuffmanSize), sizeof(int));
	
	//Completing the bits of the encoding to make a complete byte
	while(bits.size() % 8 != 0) bits.push_back(false);
	
	//Writing the enconding in the output file
	for(int i = 0; i < bits.size(); i += 8){
		//Merging the bits into a byte
		unsigned char byte = (unsigned char)(bits[i] << 7) + (unsigned char)(bits[i + 1] << 6) + 
		(unsigned char)(bits[i + 2] << 5) + (unsigned char)(bits[i + 3] << 4) + (unsigned char)(bits[i + 4] << 3) +
		(unsigned char)(bits[i + 5] << 2) + (unsigned char)(bits[i + 6] << 1) + (unsigned char)(bits[i + 7]);
		fout.write(reinterpret_cast<char *>(&byte), sizeof(unsigned char)); //Write the byte
	}

	//Close files
	fin.close();
	fout.close();
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x3468, %rsp           # imm = 0x3468
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x258(%rsp), %r15
movq %r15, %rdi
callq 0x2140
movq %r15, %rdi
movq %r14, %rsi
movl $0x4, %edx
callq 0x20e0
leaq 0x58(%rsp), %rdi
callq 0x21b0
leaq 0x58(%rsp), %rdi
movq %rbx, %rsi
movl $0x10, %edx
callq 0x2030
xorps %xmm0, %xmm0
leaq 0x30(%rsp), %rbx
movaps %xmm0, (%rbx)
xorl %eax, %eax
movq %rax, 0x10(%rbx)
movq %rax, 0x8(%rsp)
movl %eax, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movl %eax, 0x20(%rsp)
movq %rax, 0x28(%rsp)
leaq 0x460(%rsp), %rdi
movl $0x400, %edx            # imm = 0x400
xorl %esi, %esi
callq 0x20d0
leaq 0x258(%rsp), %r14
leaq 0x6(%rsp), %r15
leaq 0x860(%rsp), %r12
movq %r14, %rdi
callq 0x2090
cmpl $-0x1, %eax
je 0x245e
movl $0x1, %edx
movq %r14, %rdi
movq %r15, %rsi
callq 0x2150
movb 0x6(%rsp), %al
movb %al, 0x860(%rsp)
movq %rbx, %rdi
movq %r12, %rsi
callq 0x2b18
movzbl 0x6(%rsp), %eax
incl 0x460(%rsp,%rax,4)
jmp 0x241d
leaq 0x860(%rsp), %rdi
leaq 0x460(%rsp), %rsi
callq 0x2fcc
leaq 0x860(%rsp), %rdi
leaq 0x8(%rsp), %rsi
leaq 0x30(%rsp), %rdx
callq 0x3400
leaq 0x58(%rsp), %rdi
leaq 0x460(%rsp), %rsi
movl $0x400, %edx            # imm = 0x400
callq 0x2160
movl 0x18(%rsp), %eax
subl 0x8(%rsp), %eax
shll $0x3, %eax
addl 0x20(%rsp), %eax
leaq 0x54(%rsp), %rsi
movl %eax, (%rsi)
leaq 0x58(%rsp), %rdi
movl $0x4, %edx
callq 0x2160
leaq 0x8(%rsp), %rbx
movl 0x20(%rsp), %ecx
testb $0x7, %cl
je 0x24e0
movq %rbx, %rdi
xorl %esi, %esi
callq 0x2a9c
jmp 0x24cb
movq 0x8(%rsp), %rax
movq 0x18(%rsp), %rdx
subq %rax, %rdx
shlq $0x3, %rdx
addq %rcx, %rdx
je 0x25f0
xorl %r15d, %r15d
leaq 0x58(%rsp), %rbx
leaq 0x7(%rsp), %r14
movl %r15d, %ecx
shrl $0x6, %ecx
movl %r15d, %edx
andb $0x38, %dl
movq (%rax,%rcx,8), %rax
movzbl %dl, %ecx
btq %rcx, %rax
setb %dl
leal 0x1(%rcx), %esi
movzbl %sil, %esi
btq %rsi, %rax
setb %sil
leal 0x2(%rcx), %edi
movzbl %dil, %edi
btq %rdi, %rax
setb %dil
leal 0x3(%rcx), %r8d
movzbl %r8b, %r8d
btq %r8, %rax
setb %r8b
leal 0x4(%rcx), %r9d
movzbl %r9b, %r9d
btq %r9, %rax
setb %r9b
leal 0x5(%rcx), %r10d
movzbl %r10b, %r10d
btq %r10, %rax
setb %r10b
leal 0x6(%rcx), %r11d
movzbl %r11b, %r11d
btq %r11, %rax
setb %r11b
orb $0x7, %cl
shlb $0x7, %dl
shlb $0x6, %sil
orb %dl, %sil
shlb $0x5, %dil
orb %sil, %dil
shlb $0x4, %r8b
orb %dil, %r8b
shlb $0x3, %r9b
orb %r8b, %r9b
shlb $0x2, %r10b
orb %r9b, %r10b
addb %r11b, %r11b
orb %r10b, %r11b
movzbl %cl, %ecx
btq %rcx, %rax
adcb $0x0, %r11b
movb %r11b, 0x7(%rsp)
movl $0x1, %edx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2160
addq $0x8, %r15
movq 0x8(%rsp), %rax
movq 0x18(%rsp), %rcx
movl 0x20(%rsp), %edx
subq %rax, %rcx
leaq (%rdx,%rcx,8), %rcx
cmpq %r15, %rcx
ja 0x2507
leaq 0x258(%rsp), %rdi
callq 0x2040
leaq 0x58(%rsp), %rdi
callq 0x2170
leaq 0x860(%rsp), %rdi
callq 0x33c4
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x262b
movq 0x28(%rsp), %rsi
subq %rdi, %rsi
callq 0x2130
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x2642
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x2130
movq 0x398f(%rip), %rax      # 0x5fd8
movq (%rax), %rcx
movq 0x18(%rax), %rax
leaq 0x60(%rsp), %rdi
movq %rcx, -0x8(%rdi)
movq -0x18(%rcx), %rcx
movq %rax, 0x58(%rsp,%rcx)
callq 0x2100
leaq 0x150(%rsp), %rdi
callq 0x2070
leaq 0x258(%rsp), %rdi
callq 0x2050
addq $0x3468, %rsp           # imm = 0x3468
popq %rbx
popq %r12
popq %r14
popq %r15
retq
jmp 0x26b8
movq %rax, %rbx
jmp 0x26fd
jmp 0x2699
movq %rax, %rbx
jmp 0x2707
jmp 0x26a4
jmp 0x26a4
jmp 0x26a4
movq %rax, %rbx
leaq 0x860(%rsp), %rdi
callq 0x33c4
jmp 0x26bb
jmp 0x26b8
movq %rax, %rbx
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x26e6
movq 0x28(%rsp), %rsi
subq %rdi, %rsi
callq 0x2130
xorl %eax, %eax
movq %rax, 0x8(%rsp)
movl $0x0, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x26fd
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x2130
leaq 0x58(%rsp), %rdi
callq 0x2180
leaq 0x258(%rsp), %rdi
callq 0x2050
movq %rbx, %rdi
callq 0x21d0