// File: /workspace/github_c_makefile_star2_O0/ijleesw[P]data-compression/src/tunstall/tunstall.hpp
// Function: Tunstall::compress(unsigned char*, int, int&)
unsigned char *Tunstall::compress(unsigned char *data, int input_size, int &output_size) {
	if(probabilities.size() == 1) {
		output_size = 0;
		return NULL;
	}

	unsigned char *output = new unsigned char[input_size*2]; //use entropy here!

	assert(wordsize <= 16);
	output_size = 0;
	int input_offset = 0;
	int word_offset = 0;
	int offset = 0;
	while(input_offset < input_size) {
		//read lookup_size symbols and compute code:
		int d = input_size - input_offset;
		if(d > lookup_size)
			d = lookup_size;
		int low, high;
		wordCode(data + input_offset, d, low, high);
		offset = offsets[-offset + low];
		assert(offset != 0xffffff);
		if(offset >= 0) { //ready to ouput a symbol
			output[output_size++] = offset;
			input_offset += lengths[offset] - word_offset;
			offset = 0;
			word_offset = 0;
		} else {
			word_offset += lookup_size;
			input_offset += lookup_size;
		}
	}
	//end of stream can be tricky:
	//we could have a partial read (need to encode half a word)
	if(offset < 0) {
		while(offset < 0)
			offset = offsets[-offset];
		output[output_size++] = offset;
	}
	assert(output_size <= input_size*2);
#ifdef DEBUG_ENTROPY
	cout << "Compressed to: E: " << ((float)output_size*8.0f)/input_size << " tot: " << output_size << endl;
#endif
	return output;
}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x48(%rsp)
movq %rsi, 0x40(%rsp)
movl %edx, 0x3c(%rsp)
movq %rcx, 0x30(%rsp)
movq 0x48(%rsp), %rdi
movq %rdi, 0x8(%rsp)
addq $0x10, %rdi
callq 0x6120
cmpq $0x1, %rax
jne 0x4029
movq 0x30(%rsp), %rax
movl $0x0, (%rax)
movq $0x0, 0x50(%rsp)
jmp 0x4248
movl 0x3c(%rsp), %eax
shll %eax
movslq %eax, %rdi
movq $-0x1, %rax
cmpq $0x0, %rdi
cmovlq %rax, %rdi
callq 0x2030
movq %rax, %rcx
movq 0x8(%rsp), %rax
movq %rcx, 0x28(%rsp)
cmpl $0x10, 0x4(%rax)
jg 0x405b
jmp 0x407a
leaq 0xa06c(%rip), %rdi      # 0xe0ce
leaq 0x9fad(%rip), %rsi      # 0xe016
movl $0x20d, %edx            # imm = 0x20D
leaq 0xa068(%rip), %rcx      # 0xe0dd
callq 0x20d0
movq 0x30(%rsp), %rax
movl $0x0, (%rax)
movl $0x0, 0x24(%rsp)
movl $0x0, 0x20(%rsp)
movl $0x0, 0x1c(%rsp)
movl 0x24(%rsp), %eax
cmpl 0x3c(%rsp), %eax
jge 0x41be
movq 0x8(%rsp), %rcx
movl 0x3c(%rsp), %eax
subl 0x24(%rsp), %eax
movl %eax, 0x18(%rsp)
movl 0x18(%rsp), %eax
cmpl 0x70(%rcx), %eax
jle 0x40d1
movq 0x8(%rsp), %rax
movl 0x70(%rax), %eax
movl %eax, 0x18(%rsp)
movq 0x8(%rsp), %rdi
movq 0x40(%rsp), %rsi
movslq 0x24(%rsp), %rax
addq %rax, %rsi
movl 0x18(%rsp), %edx
leaq 0x14(%rsp), %rcx
leaq 0x10(%rsp), %r8
callq 0x6940
movq 0x8(%rsp), %rdi
addq $0x78, %rdi
xorl %eax, %eax
subl 0x1c(%rsp), %eax
addl 0x14(%rsp), %eax
movslq %eax, %rsi
callq 0x5fc0
movl (%rax), %eax
movl %eax, 0x1c(%rsp)
cmpl $0xffffff, 0x1c(%rsp)   # imm = 0xFFFFFF
je 0x4123
jmp 0x4142
leaq 0x9ff2(%rip), %rdi      # 0xe11c
leaq 0x9ee5(%rip), %rsi      # 0xe016
movl $0x21a, %edx            # imm = 0x21A
leaq 0x9fa0(%rip), %rcx      # 0xe0dd
callq 0x20d0
cmpl $0x0, 0x1c(%rsp)
jl 0x419e
movq 0x8(%rsp), %rdi
movl 0x1c(%rsp), %eax
movb %al, %dl
movq 0x28(%rsp), %rax
movq 0x30(%rsp), %rsi
movl (%rsi), %ecx
movl %ecx, %r8d
addl $0x1, %r8d
movl %r8d, (%rsi)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
addq $0x40, %rdi
movslq 0x1c(%rsp), %rsi
callq 0x5fc0
movl (%rax), %eax
subl 0x20(%rsp), %eax
addl 0x24(%rsp), %eax
movl %eax, 0x24(%rsp)
movl $0x0, 0x1c(%rsp)
movl $0x0, 0x20(%rsp)
jmp 0x41b9
movq 0x8(%rsp), %rax
movl 0x70(%rax), %ecx
addl 0x20(%rsp), %ecx
movl %ecx, 0x20(%rsp)
movl 0x70(%rax), %eax
addl 0x24(%rsp), %eax
movl %eax, 0x24(%rsp)
jmp 0x409d
cmpl $0x0, 0x1c(%rsp)
jge 0x420c
jmp 0x41c7
cmpl $0x0, 0x1c(%rsp)
jge 0x41ed
movq 0x8(%rsp), %rdi
addq $0x78, %rdi
xorl %eax, %eax
subl 0x1c(%rsp), %eax
movslq %eax, %rsi
callq 0x5fc0
movl (%rax), %eax
movl %eax, 0x1c(%rsp)
jmp 0x41c7
movl 0x1c(%rsp), %eax
movb %al, %dl
movq 0x28(%rsp), %rax
movq 0x30(%rsp), %rsi
movl (%rsi), %ecx
movl %ecx, %edi
addl $0x1, %edi
movl %edi, (%rsi)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movq 0x30(%rsp), %rax
movl (%rax), %eax
movl 0x3c(%rsp), %ecx
shll %ecx
cmpl %ecx, %eax
jg 0x421f
jmp 0x423e
leaq 0x9f09(%rip), %rdi      # 0xe12f
leaq 0x9de9(%rip), %rsi      # 0xe016
movl $0x22c, %edx            # imm = 0x22C
leaq 0x9ea4(%rip), %rcx      # 0xe0dd
callq 0x20d0
movq 0x28(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rax
addq $0x58, %rsp
retq
nopw %cs:(%rax,%rax)