// File: /workspace/github_c_makefile_star2_O1/ijleesw[P]data-compression/src/tunstall/main.cpp
// Function: main
int main(int argc, char** argv)
{
	unsigned char* data;
	unsigned int size;

	if (argc < 4) {
		cout << "Usage: "<<argv[0]<<" <input path> <compression path> <decompression path>\n";
		return -1;
	}
	if (!readchar2buf(argv[1], data, &size)) {
		perror("File open error.\n");
		return -1;
	}
	ofstream compressed(argv[2]);
	ofstream decompressed(argv[3]);

	// 8: bits of each code symbol
	// 2: n_symbol^2 lookup tables
	Tunstall t = Tunstall(8, 2);


	/******************************
	 *
	 *  Compression
	 *
	 ******************************/

	t.getProbabilities(data, size);
	t.createDecodingTables();
	t.createEncodingTables();
	int compressed_size;
	unsigned char *compressed_data = t.compress(data, size, compressed_size);
	
	compressed << (unsigned char)t.probabilities.size();
	int tmp_size = t.probabilities.size();
	for (int i = 0; i < tmp_size; i++) compressed << (unsigned char)t.probabilities[i].symbol << (unsigned char)t.probabilities[i].probability;
	
	compressed << size;
	compressed << compressed_size;

	for (int i = 0; i < compressed_size; i++) compressed << (unsigned char)compressed_data[i];

	compressed.close();

	compressed_size =  1 + t.probabilities.size()*2 + 4 + 4 + compressed_size;



	/******************************
	 *
	 *  Decompression
	 *
	 ******************************/

	int nsymbols = t.probabilities.size();
	void *probs = t.probabilities.data();
	t.probabilities.resize(nsymbols);
	memcpy(t.probabilities.data(), probs, nsymbols*2);
	t.createDecodingTables();
	unsigned char* output = (uchar*)malloc((size+1)*sizeof(uchar));
	if(size) {
		cout << "";
		t.decompress(compressed_data, compressed_size, output, size);
	}

	for (int i = 0; i < size; i++) decompressed << output[i];

	decompressed.close();

	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x4c8, %rsp            # imm = 0x4C8
movq %rsi, %rbx
cmpl $0x3, %edi
jg 0x3989
movq 0x568e(%rip), %r14      # 0x8fd8
leaq 0x285a(%rip), %rsi      # 0x61ab
movl $0x7, %edx
movq %r14, %rdi
callq 0x21a0
movq (%rbx), %rbx
testq %rbx, %rbx
je 0x3cd5
movq %rbx, %rdi
callq 0x20a0
movq 0x565f(%rip), %rdi      # 0x8fd8
movq %rbx, %rsi
movq %rax, %rdx
callq 0x21a0
jmp 0x3ced
movq 0x8(%rbx), %rdi
leaq 0x18(%rsp), %rsi
leaq 0x14(%rsp), %rdx
callq 0x373f
testl %eax, %eax
je 0x3d1c
movq 0x10(%rbx), %rsi
leaq 0xc8(%rsp), %rdi
movl $0x10, %edx
callq 0x2180
movq 0x18(%rbx), %rsi
leaq 0x2c8(%rsp), %rdi
movl $0x10, %edx
callq 0x2180
movabsq $0x8000000ff, %rax      # imm = 0x8000000FF
leaq 0x20(%rsp), %rdi
movq %rax, (%rdi)
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rdi)
movups %xmm0, 0x20(%rdi)
movups %xmm0, 0x30(%rdi)
movups %xmm0, 0x40(%rdi)
movups %xmm0, 0x50(%rdi)
movups %xmm0, 0x60(%rdi)
movl $0x2, 0x70(%rdi)
movups %xmm0, 0x78(%rdi)
movups %xmm0, 0x88(%rdi)
movups %xmm0, 0x98(%rdi)
movq 0x18(%rsp), %r14
movl 0x14(%rsp), %ebx
movq %r14, %rsi
movl %ebx, %edx
callq 0x242c
leaq 0x20(%rsp), %rdi
callq 0x2d0c
leaq 0x20(%rsp), %rdi
callq 0x31d4
leaq 0x20(%rsp), %rdi
leaq 0x10(%rsp), %rcx
movq %r14, %rsi
movl %ebx, %edx
callq 0x3432
movq %rax, %r14
movl 0x38(%rsp), %eax
subl 0x30(%rsp), %eax
shrl %eax
leaq 0xf(%rsp), %rsi
movb %al, (%rsi)
leaq 0xc8(%rsp), %rdi
movl $0x1, %edx
callq 0x21a0
movq 0x38(%rsp), %r13
subq 0x30(%rsp), %r13
shrq %r13
testl %r13d, %r13d
jle 0x3ae0
andl $0x7fffffff, %r13d      # imm = 0x7FFFFFFF
xorl %ebp, %ebp
leaq 0xc8(%rsp), %r15
leaq 0xf(%rsp), %r12
movq 0x30(%rsp), %rax
movb (%rax,%rbp,2), %al
movb %al, 0xf(%rsp)
movl $0x1, %edx
movq %r15, %rdi
movq %r12, %rsi
callq 0x21a0
movq 0x30(%rsp), %rcx
movb 0x1(%rcx,%rbp,2), %cl
movb %cl, 0xf(%rsp)
movl $0x1, %edx
movq %rax, %rdi
movq %r12, %rsi
callq 0x21a0
incq %rbp
cmpq %rbp, %r13
jne 0x3a9f
leaq 0xc8(%rsp), %rdi
movq %rbx, %rsi
callq 0x2100
movl 0x10(%rsp), %r12d
leaq 0xc8(%rsp), %rdi
movl %r12d, %esi
callq 0x2260
testl %r12d, %r12d
jle 0x3b39
xorl %ebp, %ebp
leaq 0xc8(%rsp), %r15
leaq 0xf(%rsp), %r13
movb (%r14,%rbp), %al
movb %al, 0xf(%rsp)
movl $0x1, %edx
movq %r15, %rdi
movq %r13, %rsi
callq 0x21a0
incq %rbp
cmpq %rbp, %r12
jne 0x3b19
leaq 0xc8(%rsp), %rdi
callq 0x21f0
leaq 0x30(%rsp), %rdi
movq (%rdi), %r13
movq 0x8(%rdi), %rax
subq %r13, %rax
movl %eax, %r15d
andl $-0x2, %r15d
leal (%r12,%r15), %ebp
addl $0x9, %ebp
movl %ebp, 0x10(%rsp)
shrq %rax
movslq %eax, %rsi
callq 0x433e
leaq 0x20(%rsp), %r12
movq 0x10(%r12), %rdi
movslq %r15d, %rdx
movq %r13, %rsi
callq 0x2120
movq %r12, %rdi
callq 0x2d0c
leal 0x1(%rbx), %edi
callq 0x21d0
testq %rbx, %rbx
je 0x3bf8
movq %rax, %r12
movq 0x5432(%rip), %rdi      # 0x8fd8
leaq 0x264e(%rip), %rsi      # 0x61fb
xorl %edx, %edx
callq 0x21a0
leaq 0x20(%rsp), %rdi
movq %r14, %rsi
movl %ebp, %edx
movq %r12, %rcx
movl %ebx, %r8d
callq 0x35b6
xorl %ebp, %ebp
leaq 0x2c8(%rsp), %r14
leaq 0xf(%rsp), %r13
movb (%r12,%rbp), %al
movb %al, 0xf(%rsp)
movl $0x1, %edx
movq %r14, %rdi
movq %r13, %rsi
callq 0x21a0
incq %rbp
cmpq %rbp, %rbx
jne 0x3bd8
leaq 0x2c8(%rsp), %rbx
movq %rbx, %rdi
callq 0x21f0
movq 0xb0(%rsp), %rdi
testq %rdi, %rdi
je 0x3c1a
callq 0x2160
movq 0x98(%rsp), %rdi
testq %rdi, %rdi
je 0x3c2c
callq 0x2160
movq 0x78(%rsp), %rdi
testq %rdi, %rdi
je 0x3c3b
callq 0x2160
movq 0x60(%rsp), %rdi
testq %rdi, %rdi
je 0x3c4a
callq 0x2160
movq 0x48(%rsp), %rdi
testq %rdi, %rdi
je 0x3c59
callq 0x2160
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x3c68
callq 0x2160
movq 0x5361(%rip), %rax      # 0x8fd0
movq (%rax), %r14
movq 0x18(%rax), %r15
leaq 0x2d0(%rsp), %rdi
movq %r14, -0x8(%rdi)
movq -0x18(%r14), %rax
movq %r15, 0x2c8(%rsp,%rax)
callq 0x2140
movl $0xf8, %r12d
addq %r12, %rbx
movq %rbx, %rdi
callq 0x2070
leaq 0xd0(%rsp), %rdi
movq %r14, -0x8(%rdi)
movq -0x18(%r14), %rax
movq %r15, 0xc8(%rsp,%rax)
callq 0x2140
leaq 0xc8(%rsp), %rdi
addq %r12, %rdi
callq 0x2070
xorl %eax, %eax
jmp 0x3d0a
movq (%r14), %rax
movq -0x18(%rax), %rax
leaq (%r14,%rax), %rdi
movl 0x20(%r14,%rax), %esi
orl $0x1, %esi
callq 0x2250
movq 0x52e4(%rip), %rdi      # 0x8fd8
leaq 0x24b8(%rip), %rsi      # 0x61b3
movl $0x36, %edx
callq 0x21a0
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x4c8, %rsp            # imm = 0x4C8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x24c7(%rip), %rdi      # 0x61ea
callq 0x2130
jmp 0x3d05
movq %rax, %rbx
jmp 0x3d57
jmp 0x3d3d
jmp 0x3d3d
jmp 0x3d3d
jmp 0x3d3d
jmp 0x3d3d
jmp 0x3d3d
jmp 0x3d3d
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x436e
leaq 0x2c8(%rsp), %rdi
callq 0x2210
leaq 0xc8(%rsp), %rdi
callq 0x2210
movq %rbx, %rdi
callq 0x2280