// File: /workspace/github_cpp_makefile_star2_O1/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 0x244e
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 0x2b0e
movzbl 0x6(%rsp), %eax
incl 0x460(%rsp,%rax,4)
jmp 0x240d
leaq 0x860(%rsp), %rdi
leaq 0x460(%rsp), %rsi
callq 0x2fb8
leaq 0x860(%rsp), %rdi
leaq 0x8(%rsp), %rsi
leaq 0x30(%rsp), %rdx
callq 0x3432
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
testb $0x7, 0x20(%rsp)
je 0x24ce
movq %rbx, %rdi
xorl %esi, %esi
callq 0x2a92
jmp 0x24bb
movq 0x8(%rsp), %rax
movq 0x18(%rsp), %rcx
movl 0x20(%rsp), %edx
subq %rax, %rcx
shlq $0x3, %rcx
addq %rdx, %rcx
je 0x25a9
xorl %r15d, %r15d
leaq 0x58(%rsp), %rbx
leaq 0x7(%rsp), %r14
movq %r15, %rcx
shrq $0x6, %rcx
movl %r15d, %edx
andb $0x38, %dl
movq (%rax,%rcx,8), %rax
movzbl %dl, %ecx
btq %rcx, %rax
setb %r8b
shrq %cl, %rax
movl %eax, %r10d
andb $0x2, %r10b
movl %eax, %r9d
andb $0x4, %r9b
movl %eax, %edi
andb $0x8, %dil
movl %eax, %ecx
andl $0x10, %ecx
shrl $0x4, %ecx
movl %eax, %edx
andl $0x20, %edx
shrl $0x5, %edx
movl %eax, %esi
andl $0x40, %esi
shrl $0x6, %esi
shlb $0x7, %r8b
shlb $0x5, %r10b
orb %r8b, %r10b
shlb $0x3, %r9b
orb %r10b, %r9b
addb %dil, %dil
orb %r9b, %dil
shlb $0x3, %cl
orb %dil, %cl
shlb $0x2, %dl
orb %cl, %dl
addb %sil, %sil
orb %dl, %sil
shrb $0x7, %al
addb %sil, %al
movb %al, 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 0x24f9
leaq 0x258(%rsp), %rdi
callq 0x2040
leaq 0x58(%rsp), %rdi
callq 0x2170
leaq 0x860(%rsp), %rdi
callq 0x33f6
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x25fd
movq 0x28(%rsp), %rsi
subq %rdi, %rsi
callq 0x2130
xorl %eax, %eax
movq %rax, 0x8(%rsp)
movl %eax, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movl %eax, 0x20(%rsp)
movq %rax, 0x28(%rsp)
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x2614
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x2130
movq 0x39bd(%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 0x268a
movq %rax, %rbx
jmp 0x26d4
jmp 0x266b
movq %rax, %rbx
jmp 0x26de
jmp 0x2676
jmp 0x2676
jmp 0x2676
movq %rax, %rbx
leaq 0x860(%rsp), %rdi
callq 0x33f6
jmp 0x268d
jmp 0x268a
movq %rax, %rbx
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x26bd
movq 0x28(%rsp), %rsi
subq %rdi, %rsi
callq 0x2130
xorl %eax, %eax
movq %rax, 0x8(%rsp)
movl %eax, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movl %eax, 0x20(%rsp)
movq %rax, 0x28(%rsp)
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x26d4
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