// File: dgboy2000[P]compress/compress.cpp
// Function: DATCompression::huffman_decompress(std::vector<int, std::allocator<int>>)
vector<int> DATCompression::huffman_decompress(vector<int> compressed)
{
  vector<int> decompressed;
  vector<int> code[HUFFMAN_MAX];
  int code_space[65536], position;
  int number, d = 0, power = 1, code_ind = 0, c, temp = 0, q, r, g = 0;
  int useless_bits = compressed[compressed.size() - 1];
  char status = 'd';

  memset(code_space, -1, sizeof(code_space));
  for(int i = 0; i < compressed.size() - 1; i++)
  {
    number = compressed[i];
    for(int j = 0; j < 8; j++)
    {
      if(status == 'd')
      {
        if((number & 0x80) == 0x80)
          temp += power;
        number <<= 1;
        power *= 2, d++;
        if(d == 4)
          status = 'c', c = temp;
      }
      else if(status == 'c')
      {
        if((number & 0x80) == 0x80)
          code[code_ind].push_back(1);
        else
          code[code_ind].push_back(0);
        number <<= 1;
        c--;
        if(!c)
          status = 'd', code_ind++, d = 0, power = 1, temp = 0;
        if(code_ind == HUFFMAN_MAX)
        {
          status = 't';
          // generate code space
          for(int k = 0; k < HUFFMAN_MAX; k++)
          {
            position = 0;
            for(int l = 0; l < code[k].size(); l++)
            {
              if(!code[k][l])
                position = position * 2 + 1;
              else
                position = position * 2 + 2;
            }
            code_space[position] = k;
          }
          position = 0;
        }
      }
      else if(status == 't')
      {
        if(i == compressed.size() - 2 && 8 - j == useless_bits)
          break;

        if((number & 0x80) == 0x80)
          position = position * 2 + 2;
        else
          position = position * 2 + 1;
        if(code_space[position] >= 0)
        {
          if(!g)
            q = code_space[position], g = 1;
          else
          {
            r = code_space[position], g = 0;
            decompressed.push_back(q * HUFFMAN_MAX + r);
          }
          position = 0;
        }
        number <<= 1;
      }
    }
  }

  return decompressed;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40280, %rsp          # imm = 0x40280
movq %rdx, -0x40228(%rbp)
movq %rdi, -0x40220(%rbp)
movq %rdi, %rax
movq %rax, -0x40218(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movb $0x0, -0x19(%rbp)
callq 0x8d20
leaq -0x1a0(%rbp), %rax
movq %rax, %rcx
addq $0x180, %rcx            # imm = 0x180
movq %rcx, -0x40210(%rbp)
movq %rax, -0x40208(%rbp)
movq -0x40208(%rbp), %rdi
movq %rdi, -0x40230(%rbp)
callq 0x8d20
movq -0x40230(%rbp), %rax
movq -0x40210(%rbp), %rcx
addq $0x18, %rax
cmpq %rcx, %rax
movq %rax, -0x40208(%rbp)
jne 0x42e7
movq -0x40228(%rbp), %rdi
movl $0x0, -0x401ac(%rbp)
movl $0x1, -0x401b0(%rbp)
movl $0x0, -0x401b4(%rbp)
movl $0x0, -0x401bc(%rbp)
movl $0x0, -0x401c8(%rbp)
callq 0x90a0
movq -0x40228(%rbp), %rdi
movq %rax, %rsi
subq $0x1, %rsi
callq 0x8db0
movl (%rax), %eax
movl %eax, -0x401cc(%rbp)
movb $0x64, -0x401cd(%rbp)
leaq -0x401a0(%rbp), %rdi
movl $0xff, %esi
movl $0x40000, %edx          # imm = 0x40000
callq 0x2120
movl $0x0, -0x401d4(%rbp)
movq -0x40228(%rbp), %rdi
movslq -0x401d4(%rbp), %rax
movq %rax, -0x40238(%rbp)
callq 0x90a0
movq %rax, %rcx
movq -0x40238(%rbp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x47e5
movq -0x40228(%rbp), %rdi
movslq -0x401d4(%rbp), %rsi
callq 0x8db0
movl (%rax), %eax
movl %eax, -0x401a8(%rbp)
movl $0x0, -0x401d8(%rbp)
cmpl $0x8, -0x401d8(%rbp)
jge 0x47cf
movsbl -0x401cd(%rbp), %eax
cmpl $0x64, %eax
jne 0x4477
movl -0x401a8(%rbp), %eax
andl $0x80, %eax
cmpl $0x80, %eax
jne 0x442b
movl -0x401b0(%rbp), %eax
addl -0x401bc(%rbp), %eax
movl %eax, -0x401bc(%rbp)
movl -0x401a8(%rbp), %eax
shll %eax
movl %eax, -0x401a8(%rbp)
movl -0x401b0(%rbp), %eax
shll %eax
movl %eax, -0x401b0(%rbp)
movl -0x401ac(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x401ac(%rbp)
cmpl $0x4, -0x401ac(%rbp)
jne 0x4472
movb $0x63, -0x401cd(%rbp)
movl -0x401bc(%rbp), %eax
movl %eax, -0x401b8(%rbp)
jmp 0x47b9
movsbl -0x401cd(%rbp), %eax
cmpl $0x63, %eax
jne 0x468c
movl -0x401a8(%rbp), %eax
andl $0x80, %eax
cmpl $0x80, %eax
jne 0x44f8
movslq -0x401b4(%rbp), %rax
leaq (%rax,%rax,2), %rax
leaq -0x1a0(%rbp,%rax,8), %rdi
movl $0x1, -0x401dc(%rbp)
leaq -0x401dc(%rbp), %rsi
callq 0x8ed0
jmp 0x44c4
jmp 0x4525
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x401e8(%rbp)
movl %eax, -0x401ec(%rbp)
leaq -0x1a0(%rbp), %rax
movq %rax, -0x40248(%rbp)
addq $0x180, %rax            # imm = 0x180
movq %rax, -0x40240(%rbp)
jmp 0x483d
movslq -0x401b4(%rbp), %rax
leaq (%rax,%rax,2), %rax
leaq -0x1a0(%rbp,%rax,8), %rdi
movl $0x0, -0x401f0(%rbp)
leaq -0x401f0(%rbp), %rsi
callq 0x8ed0
jmp 0x4523
jmp 0x4525
movl -0x401a8(%rbp), %eax
shll %eax
movl %eax, -0x401a8(%rbp)
movl -0x401b8(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x401b8(%rbp)
cmpl $0x0, -0x401b8(%rbp)
jne 0x457f
movb $0x64, -0x401cd(%rbp)
movl -0x401b4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x401b4(%rbp)
movl $0x0, -0x401ac(%rbp)
movl $0x1, -0x401b0(%rbp)
movl $0x0, -0x401bc(%rbp)
cmpl $0x10, -0x401b4(%rbp)
jne 0x4687
movb $0x74, -0x401cd(%rbp)
movl $0x0, -0x401f4(%rbp)
cmpl $0x10, -0x401f4(%rbp)
jge 0x467d
movl $0x0, -0x401a4(%rbp)
movl $0x0, -0x401f8(%rbp)
movslq -0x401f8(%rbp), %rax
movq %rax, -0x40250(%rbp)
movslq -0x401f4(%rbp), %rax
leaq -0x1a0(%rbp), %rdi
imulq $0x18, %rax, %rax
addq %rax, %rdi
callq 0x90a0
movq %rax, %rcx
movq -0x40250(%rbp), %rax
cmpq %rcx, %rax
jae 0x4655
movslq -0x401f4(%rbp), %rax
leaq -0x1a0(%rbp), %rdi
imulq $0x18, %rax, %rax
addq %rax, %rdi
movslq -0x401f8(%rbp), %rsi
callq 0x8db0
cmpl $0x0, (%rax)
jne 0x462e
movl -0x401a4(%rbp), %eax
shll %eax
addl $0x1, %eax
movl %eax, -0x401a4(%rbp)
jmp 0x463f
movl -0x401a4(%rbp), %eax
shll %eax
addl $0x2, %eax
movl %eax, -0x401a4(%rbp)
jmp 0x4641
movl -0x401f8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x401f8(%rbp)
jmp 0x45be
movl -0x401f4(%rbp), %ecx
movslq -0x401a4(%rbp), %rax
movl %ecx, -0x401a0(%rbp,%rax,4)
movl -0x401f4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x401f4(%rbp)
jmp 0x459d
movl $0x0, -0x401a4(%rbp)
jmp 0x47b7
movsbl -0x401cd(%rbp), %eax
cmpl $0x74, %eax
jne 0x47b5
movq -0x40228(%rbp), %rdi
movslq -0x401d4(%rbp), %rax
movq %rax, -0x40258(%rbp)
callq 0x90a0
movq %rax, %rcx
movq -0x40258(%rbp), %rax
subq $0x2, %rcx
cmpq %rcx, %rax
jne 0x46e1
movl $0x8, %eax
subl -0x401d8(%rbp), %eax
cmpl -0x401cc(%rbp), %eax
jne 0x46e1
jmp 0x47cf
movl -0x401a8(%rbp), %eax
andl $0x80, %eax
cmpl $0x80, %eax
jne 0x4706
movl -0x401a4(%rbp), %eax
shll %eax
addl $0x2, %eax
movl %eax, -0x401a4(%rbp)
jmp 0x4717
movl -0x401a4(%rbp), %eax
shll %eax
addl $0x1, %eax
movl %eax, -0x401a4(%rbp)
movslq -0x401a4(%rbp), %rax
cmpl $0x0, -0x401a0(%rbp,%rax,4)
jl 0x47a7
cmpl $0x0, -0x401c8(%rbp)
jne 0x4751
movslq -0x401a4(%rbp), %rax
movl -0x401a0(%rbp,%rax,4), %eax
movl %eax, -0x401c0(%rbp)
movl $0x1, -0x401c8(%rbp)
jmp 0x479d
movq -0x40220(%rbp), %rdi
movslq -0x401a4(%rbp), %rax
movl -0x401a0(%rbp,%rax,4), %eax
movl %eax, -0x401c4(%rbp)
movl $0x0, -0x401c8(%rbp)
movl -0x401c0(%rbp), %eax
shll $0x4, %eax
movl -0x401c4(%rbp), %ecx
addl %ecx, %eax
movl %eax, -0x401fc(%rbp)
leaq -0x401fc(%rbp), %rsi
callq 0x8ed0
jmp 0x479b
jmp 0x479d
movl $0x0, -0x401a4(%rbp)
movl -0x401a8(%rbp), %eax
shll %eax
movl %eax, -0x401a8(%rbp)
jmp 0x47b7
jmp 0x47b9
jmp 0x47bb
movl -0x401d8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x401d8(%rbp)
jmp 0x43ee
jmp 0x47d1
movl -0x401d4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x401d4(%rbp)
jmp 0x4398
movb $0x1, -0x19(%rbp)
leaq -0x1a0(%rbp), %rax
movq %rax, -0x40268(%rbp)
addq $0x180, %rax            # imm = 0x180
movq %rax, -0x40260(%rbp)
movq -0x40260(%rbp), %rdi
addq $-0x18, %rdi
movq %rdi, -0x40270(%rbp)
callq 0x8f20
movq -0x40268(%rbp), %rcx
movq -0x40270(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x40260(%rbp)
jne 0x4804
testb $0x1, -0x19(%rbp)
jne 0x4888
jmp 0x487c
movq -0x40240(%rbp), %rdi
addq $-0x18, %rdi
movq %rdi, -0x40278(%rbp)
callq 0x8f20
movq -0x40248(%rbp), %rcx
movq -0x40278(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x40240(%rbp)
jne 0x483d
movq -0x40220(%rbp), %rdi
callq 0x8f20
jmp 0x4898
movq -0x40220(%rbp), %rdi
callq 0x8f20
movq -0x40218(%rbp), %rax
addq $0x40280, %rsp          # imm = 0x40280
popq %rbp
retq
movq -0x401e8(%rbp), %rdi
callq 0x2380
nopw %cs:(%rax,%rax)