// File: 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
movq %rsp, %rbp
subq $0x35f0, %rsp           # imm = 0x35F0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x218(%rbp), %rdi
movq %rdi, -0x3520(%rbp)
callq 0x2140
movq -0x3520(%rbp), %rdi
movq -0x8(%rbp), %rsi
movl $0x4, %edx
callq 0x20e0
jmp 0x23ad
leaq -0x428(%rbp), %rdi
callq 0x21c0
jmp 0x23bb
movq -0x10(%rbp), %rsi
leaq -0x428(%rbp), %rdi
movl $0x10, %edx
callq 0x2030
jmp 0x23d2
leaq -0x440(%rbp), %rdi
callq 0x2db0
leaq -0x468(%rbp), %rdi
callq 0x2dd0
leaq -0x870(%rbp), %rdi
xorl %esi, %esi
movl $0x400, %edx            # imm = 0x400
callq 0x20d0
movl $0x0, -0x878(%rbp)
leaq -0x218(%rbp), %rdi
callq 0x2090
movl %eax, -0x3524(%rbp)
jmp 0x241b
movl -0x3524(%rbp), %eax
cmpl $-0x1, %eax
je 0x24d6
leaq -0x218(%rbp), %rdi
leaq -0x871(%rbp), %rsi
movl $0x1, %edx
callq 0x2150
jmp 0x2444
movb -0x871(%rbp), %al
movb %al, -0x879(%rbp)
leaq -0x440(%rbp), %rdi
leaq -0x879(%rbp), %rsi
callq 0x2df0
jmp 0x2465
movzbl -0x871(%rbp), %eax
movl -0x870(%rbp,%rax,4), %ecx
addl $0x1, %ecx
movl %ecx, -0x870(%rbp,%rax,4)
movl -0x878(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x878(%rbp)
jmp 0x2407
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x29a3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x2997
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x297f
leaq -0x3488(%rbp), %rdi
leaq -0x870(%rbp), %rsi
callq 0x58b0
jmp 0x24eb
leaq -0x3488(%rbp), %rdi
leaq -0x468(%rbp), %rsi
leaq -0x440(%rbp), %rdx
callq 0x6080
jmp 0x2507
leaq -0x428(%rbp), %rdi
leaq -0x870(%rbp), %rsi
movl $0x400, %edx            # imm = 0x400
callq 0x2160
jmp 0x2521
leaq -0x468(%rbp), %rdi
callq 0x2e20
movl %eax, -0x348c(%rbp)
leaq -0x428(%rbp), %rdi
leaq -0x348c(%rbp), %rsi
movl $0x4, %edx
callq 0x2160
jmp 0x254d
jmp 0x254f
leaq -0x468(%rbp), %rdi
callq 0x2e20
andq $0x7, %rax
cmpq $0x0, %rax
je 0x259a
leaq -0x468(%rbp), %rdi
xorl %esi, %esi
callq 0x2ea0
jmp 0x2575
jmp 0x254f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x3488(%rbp), %rdi
callq 0x6010
jmp 0x297f
movl $0x0, -0x3490(%rbp)
movslq -0x3490(%rbp), %rax
movq %rax, -0x3530(%rbp)
leaq -0x468(%rbp), %rdi
callq 0x2e20
movq %rax, %rcx
movq -0x3530(%rbp), %rax
cmpq %rcx, %rax
jae 0x291e
movslq -0x3490(%rbp), %rsi
leaq -0x468(%rbp), %rdi
callq 0x2f70
movq %rdx, -0x3540(%rbp)
movq %rax, -0x3538(%rbp)
jmp 0x25f4
movq -0x3540(%rbp), %rax
movq -0x3538(%rbp), %rcx
movq %rcx, -0x34a8(%rbp)
movq %rax, -0x34a0(%rbp)
leaq -0x34a8(%rbp), %rdi
callq 0x2fd0
movzbl %al, %eax
shll $0x7, %eax
movl %eax, -0x3554(%rbp)
movl -0x3490(%rbp), %eax
incl %eax
movslq %eax, %rsi
leaq -0x468(%rbp), %rdi
callq 0x2f70
movq %rdx, -0x3550(%rbp)
movq %rax, -0x3548(%rbp)
jmp 0x264f
movq -0x3550(%rbp), %rax
movq -0x3548(%rbp), %rcx
movq %rcx, -0x34b8(%rbp)
movq %rax, -0x34b0(%rbp)
leaq -0x34b8(%rbp), %rdi
callq 0x2fd0
movb %al, %cl
movl -0x3554(%rbp), %eax
movzbl %cl, %ecx
shll $0x6, %ecx
addl %ecx, %eax
movl %eax, -0x356c(%rbp)
movl -0x3490(%rbp), %eax
addl $0x2, %eax
movslq %eax, %rsi
leaq -0x468(%rbp), %rdi
callq 0x2f70
movq %rdx, -0x3568(%rbp)
movq %rax, -0x3560(%rbp)
jmp 0x26b5
movq -0x3568(%rbp), %rax
movq -0x3560(%rbp), %rcx
movq %rcx, -0x34c8(%rbp)
movq %rax, -0x34c0(%rbp)
leaq -0x34c8(%rbp), %rdi
callq 0x2fd0
movb %al, %cl
movl -0x356c(%rbp), %eax
movzbl %cl, %ecx
shll $0x5, %ecx
addl %ecx, %eax
movl %eax, -0x3584(%rbp)
movl -0x3490(%rbp), %eax
addl $0x3, %eax
movslq %eax, %rsi
leaq -0x468(%rbp), %rdi
callq 0x2f70
movq %rdx, -0x3580(%rbp)
movq %rax, -0x3578(%rbp)
jmp 0x271b
movq -0x3580(%rbp), %rax
movq -0x3578(%rbp), %rcx
movq %rcx, -0x34d8(%rbp)
movq %rax, -0x34d0(%rbp)
leaq -0x34d8(%rbp), %rdi
callq 0x2fd0
movb %al, %cl
movl -0x3584(%rbp), %eax
movzbl %cl, %ecx
shll $0x4, %ecx
addl %ecx, %eax
movl %eax, -0x359c(%rbp)
movl -0x3490(%rbp), %eax
addl $0x4, %eax
movslq %eax, %rsi
leaq -0x468(%rbp), %rdi
callq 0x2f70
movq %rdx, -0x3598(%rbp)
movq %rax, -0x3590(%rbp)
jmp 0x2781
movq -0x3598(%rbp), %rax
movq -0x3590(%rbp), %rcx
movq %rcx, -0x34e8(%rbp)
movq %rax, -0x34e0(%rbp)
leaq -0x34e8(%rbp), %rdi
callq 0x2fd0
movl -0x359c(%rbp), %ecx
movzbl %al, %edx
movl %ecx, %eax
movl %edx, %ecx
leal (%rax,%rcx,8), %eax
movl %eax, -0x35b4(%rbp)
movl -0x3490(%rbp), %eax
addl $0x5, %eax
movslq %eax, %rsi
leaq -0x468(%rbp), %rdi
callq 0x2f70
movq %rdx, -0x35b0(%rbp)
movq %rax, -0x35a8(%rbp)
jmp 0x27e7
movq -0x35b0(%rbp), %rax
movq -0x35a8(%rbp), %rcx
movq %rcx, -0x34f8(%rbp)
movq %rax, -0x34f0(%rbp)
leaq -0x34f8(%rbp), %rdi
callq 0x2fd0
movl -0x35b4(%rbp), %ecx
movzbl %al, %edx
movl %ecx, %eax
movl %edx, %ecx
leal (%rax,%rcx,4), %eax
movl %eax, -0x35cc(%rbp)
movl -0x3490(%rbp), %eax
addl $0x6, %eax
movslq %eax, %rsi
leaq -0x468(%rbp), %rdi
callq 0x2f70
movq %rdx, -0x35c8(%rbp)
movq %rax, -0x35c0(%rbp)
jmp 0x284d
movq -0x35c8(%rbp), %rax
movq -0x35c0(%rbp), %rcx
movq %rcx, -0x3508(%rbp)
movq %rax, -0x3500(%rbp)
leaq -0x3508(%rbp), %rdi
callq 0x2fd0
movl -0x35cc(%rbp), %ecx
movzbl %al, %edx
movl %ecx, %eax
movl %edx, %ecx
leal (%rax,%rcx,2), %eax
movl %eax, -0x35e4(%rbp)
movl -0x3490(%rbp), %eax
addl $0x7, %eax
movslq %eax, %rsi
leaq -0x468(%rbp), %rdi
callq 0x2f70
movq %rdx, -0x35e0(%rbp)
movq %rax, -0x35d8(%rbp)
jmp 0x28b3
movq -0x35e0(%rbp), %rax
movq -0x35d8(%rbp), %rcx
movq %rcx, -0x3518(%rbp)
movq %rax, -0x3510(%rbp)
leaq -0x3518(%rbp), %rdi
callq 0x2fd0
movb %al, %cl
movl -0x35e4(%rbp), %eax
movzbl %cl, %ecx
addl %ecx, %eax
movb %al, -0x3491(%rbp)
leaq -0x428(%rbp), %rdi
leaq -0x3491(%rbp), %rsi
movl $0x1, %edx
callq 0x2160
jmp 0x2908
jmp 0x290a
movl -0x3490(%rbp), %eax
addl $0x8, %eax
movl %eax, -0x3490(%rbp)
jmp 0x25a4
leaq -0x218(%rbp), %rdi
callq 0x2050
jmp 0x292c
leaq -0x428(%rbp), %rdi
callq 0x2170
jmp 0x293a
leaq -0x3488(%rbp), %rdi
callq 0x6010
leaq -0x468(%rbp), %rdi
callq 0x3000
leaq -0x440(%rbp), %rdi
callq 0x3020
leaq -0x428(%rbp), %rdi
callq 0x2180
leaq -0x218(%rbp), %rdi
callq 0x2060
addq $0x35f0, %rsp           # imm = 0x35F0
popq %rbp
retq
leaq -0x468(%rbp), %rdi
callq 0x3000
leaq -0x440(%rbp), %rdi
callq 0x3020
leaq -0x428(%rbp), %rdi
callq 0x2180
leaq -0x218(%rbp), %rdi
callq 0x2060
movq -0x220(%rbp), %rdi
callq 0x21e0
nopl (%rax,%rax)