// File: /workspace/github_c_makefile_star2_O0/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:
subq $0x528, %rsp            # imm = 0x528
movl $0x0, 0x524(%rsp)
movl %edi, 0x520(%rsp)
movq %rsi, 0x518(%rsp)
cmpl $0x4, 0x520(%rsp)
jge 0x49e0
movq 0xf636(%rip), %rdi      # 0x13fd8
leaq 0x97a2(%rip), %rsi      # 0xe14b
callq 0x2140
movq %rax, %rdi
movq 0x518(%rsp), %rax
movq (%rax), %rsi
callq 0x2140
movq %rax, %rdi
leaq 0x9788(%rip), %rsi      # 0xe153
callq 0x2140
movl $0xffffffff, 0x524(%rsp) # imm = 0xFFFFFFFF
jmp 0x4dab
movq 0x518(%rsp), %rax
movq 0x8(%rax), %rdi
leaq 0x510(%rsp), %rsi
leaq 0x50c(%rsp), %rdx
callq 0x45a0
cmpl $0x0, %eax
jne 0x4a22
leaq 0x977d(%rip), %rdi      # 0xe18a
callq 0x2110
movl $0xffffffff, 0x524(%rsp) # imm = 0xFFFFFFFF
jmp 0x4dab
movq 0x518(%rsp), %rax
movq 0x10(%rax), %rsi
leaq 0x308(%rsp), %rdi
movl $0x10, %edx
movl %edx, 0x18(%rsp)
callq 0x2160
movl 0x18(%rsp), %edx
movq 0x518(%rsp), %rax
movq 0x18(%rax), %rsi
leaq 0x108(%rsp), %rdi
callq 0x2160
jmp 0x4a63
leaq 0x50(%rsp), %rdi
movl $0x8, %esi
movl $0x2, %edx
callq 0x6ad0
jmp 0x4a79
movq 0x510(%rsp), %rsi
movl 0x50c(%rsp), %edx
leaq 0x50(%rsp), %rdi
callq 0x23e0
jmp 0x4a94
leaq 0x50(%rsp), %rdi
callq 0x3500
jmp 0x4aa0
leaq 0x50(%rsp), %rdi
callq 0x3c70
jmp 0x4aac
movq 0x510(%rsp), %rsi
movl 0x50c(%rsp), %edx
leaq 0x50(%rsp), %rdi
leaq 0x4c(%rsp), %rcx
callq 0x3fe0
movq %rax, 0x10(%rsp)
jmp 0x4ad1
movq 0x10(%rsp), %rax
movq %rax, 0x40(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x6120
movzbl %al, %esi
leaq 0x308(%rsp), %rdi
callq 0x2210
jmp 0x4af7
leaq 0x50(%rsp), %rdi
addq $0x10, %rdi
callq 0x6120
movl %eax, 0x3c(%rsp)
movl $0x0, 0x38(%rsp)
movl 0x38(%rsp), %eax
cmpl 0x3c(%rsp), %eax
jge 0x4bc8
leaq 0x60(%rsp), %rdi
movslq 0x38(%rsp), %rsi
callq 0x6320
movzbl (%rax), %esi
leaq 0x308(%rsp), %rdi
callq 0x2210
movq %rax, 0x8(%rsp)
jmp 0x4b45
leaq 0x60(%rsp), %rdi
movslq 0x38(%rsp), %rsi
callq 0x6320
movq 0x8(%rsp), %rdi
movzbl 0x1(%rax), %esi
callq 0x2210
jmp 0x4b64
jmp 0x4b66
movl 0x38(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x38(%rsp)
jmp 0x4b11
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x100(%rsp)
movl %eax, 0xfc(%rsp)
jmp 0x4d9c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x100(%rsp)
movl %eax, 0xfc(%rsp)
jmp 0x4d8f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x100(%rsp)
movl %eax, 0xfc(%rsp)
leaq 0x50(%rsp), %rdi
callq 0x6c10
jmp 0x4d8f
movl 0x50c(%rsp), %esi
leaq 0x308(%rsp), %rdi
callq 0x21c0
jmp 0x4bde
movl 0x4c(%rsp), %esi
leaq 0x308(%rsp), %rdi
callq 0x2260
jmp 0x4bf1
movl $0x0, 0x34(%rsp)
movl 0x34(%rsp), %eax
cmpl 0x4c(%rsp), %eax
jge 0x4c2f
movq 0x40(%rsp), %rax
movslq 0x34(%rsp), %rcx
movzbl (%rax,%rcx), %esi
leaq 0x308(%rsp), %rdi
callq 0x2210
jmp 0x4c20
jmp 0x4c22
movl 0x34(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x34(%rsp)
jmp 0x4bf9
leaq 0x308(%rsp), %rdi
callq 0x21e0
jmp 0x4c3e
leaq 0x60(%rsp), %rdi
movq %rdi, (%rsp)
callq 0x6120
movq (%rsp), %rdi
movl 0x4c(%rsp), %edx
movl %eax, %ecx
movl %edx, %eax
leal 0x9(%rax,%rcx,2), %eax
movl %eax, 0x4c(%rsp)
callq 0x6120
movq (%rsp), %rdi
movl %eax, 0x30(%rsp)
callq 0x6b50
movq (%rsp), %rdi
movq %rax, 0x28(%rsp)
movslq 0x30(%rsp), %rsi
callq 0x6b70
jmp 0x4c87
leaq 0x60(%rsp), %rdi
callq 0x6b50
movq %rax, %rdi
movq 0x28(%rsp), %rsi
movl 0x30(%rsp), %eax
addl %eax, %eax
movslq %eax, %rdx
callq 0x2100
leaq 0x50(%rsp), %rdi
callq 0x3500
jmp 0x4cb3
movl 0x50c(%rsp), %eax
addl $0x1, %eax
movl %eax, %eax
movl %eax, %edi
shlq $0x0, %rdi
callq 0x21b0
movq %rax, 0x20(%rsp)
cmpl $0x0, 0x50c(%rsp)
je 0x4d0e
movq 0xf2f8(%rip), %rdi      # 0x13fd8
leaq 0x94b4(%rip), %rsi      # 0xe19b
callq 0x2140
jmp 0x4cee
movq 0x40(%rsp), %rsi
movl 0x4c(%rsp), %edx
movq 0x20(%rsp), %rcx
movl 0x50c(%rsp), %r8d
leaq 0x50(%rsp), %rdi
callq 0x4260
movl $0x0, 0x1c(%rsp)
movl 0x1c(%rsp), %eax
cmpl 0x50c(%rsp), %eax
jae 0x4d4f
movq 0x20(%rsp), %rax
movslq 0x1c(%rsp), %rcx
movzbl (%rax,%rcx), %esi
leaq 0x108(%rsp), %rdi
callq 0x2210
jmp 0x4d40
jmp 0x4d42
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x4d16
leaq 0x108(%rsp), %rdi
callq 0x21e0
jmp 0x4d5e
movl $0x0, 0x524(%rsp)
leaq 0x50(%rsp), %rdi
callq 0x6c10
leaq 0x108(%rsp), %rdi
callq 0x2200
leaq 0x308(%rsp), %rdi
callq 0x2200
jmp 0x4dab
leaq 0x108(%rsp), %rdi
callq 0x2200
leaq 0x308(%rsp), %rdi
callq 0x2200
jmp 0x4dba
movl 0x524(%rsp), %eax
addq $0x528, %rsp            # imm = 0x528
retq
movq 0x100(%rsp), %rdi
callq 0x2280
nopw (%rax,%rax)