// File: /workspace/github_cpp_makefile_star2_O2/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 %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x3478, %rsp           # imm = 0x3478
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x268(%rsp), %r15
movq %r15, %rdi
callq 0x1120
pushq $0x4
popq %rdx
movq %r15, %rdi
movq %r14, %rsi
callq 0x10d0
leaq 0x68(%rsp), %rdi
callq 0x1190
leaq 0x68(%rsp), %rdi
pushq $0x10
popq %rdx
movq %rbx, %rsi
callq 0x1030
leaq 0x50(%rsp), %rbx
andq $0x0, 0x10(%rbx)
andq $0x0, 0x8(%rsp)
andl $0x0, 0x10(%rsp)
andq $0x0, 0x18(%rsp)
xorps %xmm0, %xmm0
andl $0x0, 0x20(%rsp)
movaps %xmm0, (%rbx)
andq $0x0, 0x28(%rsp)
leaq 0x470(%rsp), %rdi
movl $0x400, %edx            # imm = 0x400
xorl %esi, %esi
callq 0x10c0
leaq 0x268(%rsp), %r14
leaq 0x6(%rsp), %r15
pushq $0x1
popq %r12
leaq 0x870(%rsp), %r13
movq %r14, %rdi
callq 0x1080
cmpl $-0x1, %eax
je 0x13f3
movq %r14, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x1130
movb 0x6(%rsp), %al
movb %al, 0x870(%rsp)
movq %rbx, %rdi
movq %r13, %rsi
callq 0x1a40
movzbl 0x6(%rsp), %eax
incl 0x470(%rsp,%rax,4)
jmp 0x13b4
leaq 0x870(%rsp), %rdi
leaq 0x470(%rsp), %rsi
callq 0x203c
leaq 0x870(%rsp), %rdi
leaq 0x8(%rsp), %rsi
leaq 0x50(%rsp), %rdx
callq 0x2408
leaq 0x68(%rsp), %rdi
leaq 0x470(%rsp), %rsi
movl $0x400, %edx            # imm = 0x400
callq 0x1140
movl 0x18(%rsp), %eax
subl 0x8(%rsp), %eax
shll $0x3, %eax
addl 0x20(%rsp), %eax
leaq 0x4c(%rsp), %rsi
movl %eax, (%rsi)
leaq 0x68(%rsp), %rdi
pushq $0x4
popq %rdx
callq 0x1140
leaq 0x8(%rsp), %rbx
movl 0x20(%rsp), %eax
testb $0x7, %al
je 0x1472
movq %rbx, %rdi
xorl %esi, %esi
callq 0x196c
jmp 0x145e
xorl %ebx, %ebx
leaq 0x8(%rsp), %r15
movq 0x18(%rsp), %rcx
subq 0x8(%rsp), %rcx
movl %eax, %eax
leaq (%rax,%rcx,8), %rax
cmpq %rbx, %rax
jbe 0x15c7
movq %r15, %rdi
movq %rbx, %rsi
callq 0x19aa
movq %rdx, %r14
andq (%rax), %r14
incq %rbx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x19aa
movq %rdx, %rbp
andq (%rax), %rbp
incq %rbx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x19aa
movq %rdx, %r12
andq (%rax), %r12
incq %rbx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x19aa
movq %rdx, %r13
movq %rbp, 0x38(%rsp)
movq %r14, 0x40(%rsp)
andq (%rax), %r13
incq %rbx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x19aa
movq %rdx, %r14
andq (%rax), %r14
incq %rbx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x19aa
movq %rdx, %rbp
andq (%rax), %rbp
incq %rbx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x19aa
movq %rdx, 0x30(%rsp)
movq %r15, %rdi
movq (%rax), %r15
incq %rbx
movq %rbx, %rsi
callq 0x19aa
testq %rbp, %rbp
setne %cl
testq %r14, %r14
setne %sil
testq %r13, %r13
setne %r8b
testq %r12, %r12
setne %r9b
cmpq $0x0, 0x38(%rsp)
setne %r10b
cmpq $0x0, 0x40(%rsp)
setne %r11b
testq %r15, 0x30(%rsp)
setne %dil
shlb $0x7, %r11b
shlb $0x6, %r10b
orb %r11b, %r10b
shlb $0x5, %r9b
orb %r10b, %r9b
shlb $0x4, %r8b
orb %r9b, %r8b
shlb $0x3, %sil
orb %r8b, %sil
shlb $0x2, %cl
orb %sil, %cl
addb %dil, %dil
orb %cl, %dil
andq (%rax), %rdx
cmpq $0x1, %rdx
sbbb $-0x1, %dil
movb %dil, 0x7(%rsp)
leaq 0x68(%rsp), %rdi
leaq 0x7(%rsp), %rsi
pushq $0x1
popq %rdx
callq 0x1140
movl 0x20(%rsp), %eax
incq %rbx
jmp 0x1474
leaq 0x268(%rsp), %rdi
callq 0x1040
leaq 0x68(%rsp), %rdi
callq 0x1150
leaq 0x870(%rsp), %rdi
callq 0x23d4
leaq 0x8(%rsp), %rdi
callq 0x19c8
leaq 0x50(%rsp), %rdi
callq 0x19e4
leaq 0x68(%rsp), %rdi
callq 0x1160
leaq 0x268(%rsp), %rdi
callq 0x1050
addq $0x3478, %rsp           # imm = 0x3478
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x1660
movq %rax, %rbx
jmp 0x1677
jmp 0x1631
movq %rax, %rbx
jmp 0x1681
jmp 0x164c
jmp 0x164c
jmp 0x164c
jmp 0x164c
jmp 0x164c
jmp 0x164c
jmp 0x164c
jmp 0x164c
jmp 0x164c
jmp 0x164c
jmp 0x164c
movq %rax, %rbx
leaq 0x870(%rsp), %rdi
callq 0x23d4
jmp 0x1663
jmp 0x1660
movq %rax, %rbx
leaq 0x8(%rsp), %rdi
callq 0x19c8
leaq 0x50(%rsp), %rdi
callq 0x19e4
leaq 0x68(%rsp), %rdi
callq 0x1160
leaq 0x268(%rsp), %rdi
callq 0x1050
movq %rbx, %rdi
callq 0x11b0